2014-09-22 84 views
0

使用休眠选择时间戳字段获取错误时间。使用休眠选择时间戳字段获取错误时间选择


我们使用Hibernate框架和Postgres数据库。

我们有一张表,它在数据类型TIMESTAMP WITH TIME ZONE的列中存储'created_time'。

+------------------------------------------+ 
+ created_time + 
+------------------------------------------+ 
+ 2014-09-22 04:30:00.756 + 
+ -----------------------------------------+ 

假设我们有一个数据'2014年9月22日04:30:00.756' 在 'CREATED_TIME'

我用下面的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 
} 

当我去throught在DataList我发现日期是正确的到来,但时间是别的东西像'11:45:00.345'

如果我在pgAdminIII中使用了相同的查询,则表示它正确地进入。

但随着休眠它错了。

我甚至试过SQL查询。我仍然面对错误的时间问题。

我没有得到解决方案,当我搜索网络。

回答

1

可能你正在获取本地时区而不是服务器时区。 因此,要获得服务器的时间戳,因为它是改变你的查询类似下面:

query= "SELECT column1,column2,createdTime at time zone current_setting('TIMEZONE') FROM TableName"; 
+1

正确。 Postgres将日期时间值转换并存储到UTC。默认情况下,检索时会应用当前的默认时区,并将调整后的值返回给客户端(pgAdmin)。由于时区信息未被存储,'TIMESTAMP WITH TIME ZONE'是一个误用。更好的名字应该是'TIMESTAMP WITH RESPECT FOR TIME ZONE'。因此,对于检索指定您想要的时区,是UTC或本地[时区名称](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。 – 2014-09-22 17:33:00

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> 

应用的解决方法是非常简单的;例如,如果你正在使用persistence.xml文件,你的Hibernate,只需添加一行里面persistence-unit标签:

<class>com.montrosesoftware.dbassist.types</class> 

对于其他的Hibernate配置,e.g与Spring启动,请参阅GitHub的项目页面。无论如何,修复程序在此步骤后立即生效,现在通过Hibernate读取(并保存到)数据库的所有日期都被视为UTC。