我们面临一个与基于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)应用程序运行的时区 - 美国东部时间。
答案 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,
一切都应该没问题。