使用hibernate选择时间戳字段的时间错误

时间:2014-09-22 15:53:04

标签: java mysql sql hibernate postgresql

使用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查询。我仍面临错误的时间问题。

我在搜索网络时没有得到解决方案。

2 个答案:

答案 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。