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

时间:2017-02-22 17:44:15

标签: java hibernate postgresql-9.4

我们面临一个与基于Java的hibernate-spring REST API在Postgres表中存储时间戳的DEFAULT值有关的问题。

该列设置为

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

我们不会从代码中发送任何时间戳值。 这就是我们在实体类中指定时间戳字段的方式。

@Column(name = "LOAD_TS", insertable = false, updatable = false)
    private Timestamp loadTimeStamp; 

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

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

实际 - 当插入请求进入数据库而没有向DB发送任何load_ts值时,load_ts将设置为EASTERN TIME + 10小时。 API正在东部时间运行。

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

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

2)春天 - 4.2

3)Postgres - 9.4

4)Postgres驱动程序 - 9.4.1212.jre7

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

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

1 个答案:

答案 0 :(得分:1)

您的列定义没有意义。函数now()返回类型timestamp with time zone。函数timezone()包含多个重载变体,但最终调用的函数返回timestamp without time zone。然后将其插入到timestamp with time zone类型的列中。

我不想绕过这里发生的事情,但我想,因为美国东部时间和UTC通常相隔5小时,而你得到10小时的差异,你可能有时间区域偏移应用两次。

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

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

一切都应该没问题。