2008-11-14 40 views
27

将日期分配给指定的SQL参数时,Hibernate会自动将其转换为GMT时间。你如何让它在所有日期使用当前的服务器时区?如何将日期参数分配给当前时区的Hibernate查询?

比方说你有一个查询:

Query q = session.createQuery("from Table where date_field < :now"); 
q.setDate("now", new java.util.Date()); 

“现在”将被设置为GMT时间,而“新的Date()”获得当前的服务器时间。

谢谢。

回答

57

事实证明,Hibernate不会自动将日期转换为GMT,如果您使用query.setDate(),它只会中断时间,所以如果您通过“2009-01-16 12:13:14”它会变成“2009-01 -16 00:00:00“。

要考虑时间,您需要使用query.setTimestamp("date", dateObj)来代替。

+1

这也只是咬我一口。在Oracle中,`DATE`是一个日期和时间,它与Java的Date相匹配,而TIMESTAMP是一个微秒的日期和时间。 – 2012-02-29 23:05:22

2

休眠不知道时区。任何时区转换都应在执行查询之前完成。例如,如果您的数据库服务器设置为CST,但用户在EST上,则需要将1小时添加到作为查询输入的任何时间戳。

2

我们使用自定义的Hibernate日期类型。任何时候我们在查询中设置参数时,我们都会使用基类或实用工具方法,以便将用户的时区传递到自定义类型参数中。

您可以通过手动调整实用程序方法中查询的时间来获取,但这样读取或写入数据库的日期也可以正确转换。此方法还处理数据库将日期存储在其本地时区中的情况。所以,即使你在一个时区内有一个用户,在另一个时区内有一个数据库服务器,而使用GMT的Java也可以让所有事情都变得直截了当。它结束了看起来像:

Properties properties = new Properties(); 
properties.setProperty("timeZone", databaseTimeZone); 
query.setParameter("from", dateEnteredByUser, Hibernate.custom(LocalizedDateType.class, properties)); 

作为额外的奖励,我们用这个对付的SQL Server转换23的事实:59:59.999到第二天。在自定义类型中,我们检查并退回。

2

如果您需要timeZone同步值,您可以在您的HQL中使用now()。另外我建议你使用Joda库。它有一个hibernate插件模块。

相关问题