未正确使用 Postgres 时间戳列的默认值设置

DEFAULT value setting of Postgres timestamp column not getting used correctly

我们正面临一个问题,该问题与基于 Java 的休眠-spring REST API 在 Postgres table 中存储时间戳的默认值有关。

列设置为

load_ts timestamp with time zone DEFAULT timezone('utc'::text, now()) NOT NULL,

我们不会从我们的代码中发送任何时间戳值。 这就是我们在实体 class.

中指定时间戳字段的方式
@Column(name = "LOAD_TS", insertable = false, updatable = false)
    private Timestamp loadTimeStamp; 

我们正在使用 Amazon RDS Postgres 数据库。 DB 参数组值 'timezone' 设置为 'UTC'。

预期 - 当插入请求到达数据库而没有向数据库发送任何 load_ts 值时,load_ts 应该根据默认设置获得 UTC 时间戳。

实际 - 当插入请求到达数据库而没有向数据库发送任何 load_ts 值时,load_ts 被设置为东部时间 + 10 小时。 API 在东部时间是 运行。

当我们在数据库中手动插入记录时,会正确生成并存储时间戳。我们查看了 RDS postgres 中的 log_statements,但没有看到 API 在插入查询中发送任何时间戳。另一个有趣的观察是,当我们将 API 时区更改为 UTC 时,时间戳会正确存储。所以不知何故 API 正在将时区传达给数据库。

应用程序堆栈 - 1) Hibernate 核心版本 - 5.0.7

2) Spring - 4.2

3) Postgres - 9.4

4) Postgres 驱动程序 - 9.4.1212.jre7

5) RDS Postgres DB 时区参数组值 - UTC

6) 应用程序的时区 运行 美国东部时间。

您的列定义没有意义。函数 now() returns 类型 timestamp with time zone。函数 timezone() 有几个重载变体,但您最终调用的是 returns timestamp without time zone。然后将其插入 timestamp with time zone.

类型的列中

我不想全神贯注于这里实际发生的事情,但我想自 U.S 以来。东部时间和 UTC 通常相隔 5 小时,而你得到 10 小时的差异,你可能应用了两次时区偏移。

根据您的描述,我认为您真正想要的是将您的列简单地定义为

load_ts timestamp with time zone DEFAULT now() NOT NULL,

一切都会好起来的。