使用Hibernate选择时间戳字段的时间错误。
我们正在使用Hibernate框架和Postgres数据库。
我们有一个表,用于在数据类型TIMESTAMP WITH TIME ZONE的列中存储'created_time'。
+------------------------------------------+
+ created_time +
+------------------------------------------+
+ 2014-09-22 04:30:00.756 +
+ -----------------------------------------+
假设我们在' created_time '中有数据'2014-09-22 04:30:00.756'。
我使用了以下hibernate查询
query= "SELECT column1,column2,createdTime FROM TableName";
…
…
List<Object[]> dataList=selectQuery.list();
for(Object data[] : dataList)
{
System.out.println("Date and time -> "+data[2].toString()); //Time coming wrong here
}
当我浏览dataList时,我发现日期正确,但时间是'11:45:00.345'。
如果我在pgAdminIII中使用相同的查询,则意味着它正确无误。
但是对于hibernate来说,这是错误的。
我甚至尝试过SQL查询。我仍面临错误的时间问题。
我在搜索网络时没有得到解决方案。
答案 0 :(得分:1)
可能您正在获取本地时区而不是服务器时区。 因此,要获取服务器的时间戳,请将查询更改为以下内容:
query= "SELECT column1,column2,createdTime at time zone current_setting('TIMEZONE') FROM TableName";
答案 1 :(得分:1)
当我们想要从DB读取/写入日期并将它们存储在UTC时区时,这是一个常见问题。例如,如果使用Hibernate从DB读取时间9:54
的日期,感谢JDBC,我们得到9:54
时间,但被解释为本地日期;对我而言,这将是9:54 UTC+2
。这意味着在Java方面我们只有7:54 UTC
时间。在此article中有更好的解释此问题。
无论如何,您可以使用小型DbAssist
开源库轻松修复它。它将标准Date
字段映射到自定义UtcDateType
,这会强制Hibernate将日期视为UTC。您可以在项目github wiki上找到有关受支持的Hibernate版本和安装指南的更多详细信息。
如果您使用JPA注释来映射实体,只需添加以下依赖项:
<dependency>
<groupId>com.montrosesoftware</groupId>
<artifactId>DbAssist-5.2.2</artifactId>
<version>1.0-RELEASE</version>
</dependency>
应用修复非常简单;例如,如果您在Hibernate中使用persistence.xml
文件,只需在persistence-unit
标记内添加一行:
<class>com.montrosesoftware.dbassist.types</class>
对于其他Hibernate配置,例如Spring Boot,请参阅github项目页面。无论如何,修复在此步骤之后立即生效,现在通过Hibernate从DB读取(并保存到)的所有日期都被视为UTC。