发布于 2013-01-19 03:41:20
我刚刚在一个类似的问题上花了6个小时,我想我应该在这里记录它。Hibernate确实使用了JVM时区,但是可以通过如下方式扩展CalendarType来更改:
public class UTCCalendarType extends CalendarType {
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
/**
* This is the original code from the class, with two changes. First we pull
* it out of the result set with an example Calendar. Second, we set the new
* calendar up in UTC.
*/
@Override
public Object get(ResultSet rs, String name) throws SQLException {
Timestamp ts = rs.getTimestamp(name, new GregorianCalendar(UTC));
if (ts != null) {
Calendar cal = new GregorianCalendar(UTC);
cal.setTime(ts);
return cal;
} else {
return null;
}
}
@Override
public void set(PreparedStatement st, Object value, int index) throws SQLException {
final Calendar cal = (Calendar) value;
cal.setTimeZone(UTC);
st.setTimestamp(index, new Timestamp(cal.getTime().getTime()), cal);
}
}
这里的秘诀是:
rs.getTimestamp(name, new GregorianCalendar(UTC));
这会将结果集的时区转换为所需的任何时区。所以我所做的就是对任何UTC日历使用这个类型,对本地时间使用标准的Hibernate类型。就像吹口哨一样灵巧...
发布于 2017-04-19 17:59:57
默认情况下,由JDBC驱动程序决定使用哪个时区。通常,除非将JDBC驱动程序配置为使用自定义时区,否则将使用JVM时区。
如果希望控制使用哪个时区,可以在JVM级别设置时区。如果希望JVM时区与数据库使用的时区不同,则需要使用hibernate.jdbc.time_zone
Hibernate 5.2配置属性:
<property name="hibernate.jdbc.time_zone" value="US/Eastern"/>
发布于 2016-11-08 21:50:49
如果您不想自己编写代码,可以只使用开源库DbAssist
。应用此修复后,JDBC将数据库中的日期视为UTC,然后Hibernate将其视为UTC,因此您甚至不必更改实体类。
例如,如果您在Hibernate 4.3.11中使用JPA注释,请添加以下Maven依赖项:
<dependency>
<groupId>com.montrosesoftware</groupId>
<artifactId>DbAssist-4.3.11</artifactId>
<version>1.0-RELEASE</version>
</dependency>
然后,您只需应用修复:
对于Hibernate + Spring Boot设置,在应用程序类之前添加@EnableAutoConfiguration
注释。
对于HBM文件,您必须更改实体映射文件,以将Date
类型映射到自定义类型:
<property name="createdAt" type="com.montrosesoftware.dbassist.types.UtcDateType" column="created_at"/>
如果你想了解更多关于如何为不同的Hibernate版本(或HBM文件)应用补丁的信息,请参考the project's github。您还可以在此article中阅读有关时区转换问题的更多信息。
https://stackoverflow.com/questions/4117249
复制相似问题