我正在尝试坚持java.time.LocalDateTime
使用 Hibernate 和 JPA。我使用了 Jadira 框架(“org.jadira.usertype:usertype.core:3.2.0.GA”和“org.jadira.usertype:usertype.extended:3.2.0.GA”)。我创建了package-info.java
文件并在@TypeDefs({@TypeDef(defaultForType = java.time.LocalDateTime.class, typeClass = org.jadira.usertype.dateandtime.threeten.PersistentLocalDateTime.class)})
那里创建。我测试了解决方案,并且这些字段正确地以列(几乎java.time.LocalDateTime
)的形式存储/检索到我的 MySQL 数据库中。DATETIME
唯一的问题是数据库中的值与 Java 中字段的正确时间值相差 +2 小时。我在 CEST (UTC+2) 所以我明白这是时区的一些问题。我调试了代码,PersistentLocalDateTime
这就是我发现的。
PersistentLocalDateTime
正在使用org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
AbstractTimestampThreeTenColumnMapper
字段ZoneOffset databaseZone
默认设置为ZoneOffset.of("Z")
(UTC)。- 因为它认为我的数据库在 UTC 时区(并且应用程序在 UTC+2),所以它在转换到数据库期间增加了两个小时(并在从数据库转换期间从我的时间中减去了两个小时)。所以在应用程序中我看到了正确的日期和时间,但在数据库中我没有。
我发现 a 可以添加参数,@TypeDef
所以我将它们指定如下:
@TypeDef(defaultForType = LocalDateTime.class, typeClass = PersistentLocalDateTime.class,
parameters = {
@Parameter(name = "databaseZone", value = "+02:00")
}),
但我有一个例外:
java.lang.IllegalStateException: Could not map Zone +02:00 to Calendar
at org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper.getHibernateType(AbstractTimestampThreeTenColumnMapper.java:59)
我又调试了一点。AbstractTimestampThreeTenColumnMapper
有两种方法:
public final DstSafeTimestampType getHibernateType() {
if (databaseZone == null) {
return DstSafeTimestampType.INSTANCE;
}
Calendar cal = resolveCalendar(databaseZone);
if (cal == null) {
throw new IllegalStateException("Could not map Zone " + databaseZone + " to Calendar");
}
return new DstSafeTimestampType(cal);
}
private Calendar resolveCalendar(ZoneOffset databaseZone) {
String id = databaseZone.getId();
if (Arrays.binarySearch(TimeZone.getAvailableIDs(), id) != -1) {
return Calendar.getInstance(TimeZone.getTimeZone(id));
} else {
return null;
}
}
getHibernateType
方法抛出异常,因为resolveCalendar
方法返回null
。为什么它会返回null
?java.time.ZoneOffset
因为来自和的时区 IDjava.util.TimeZone
不匹配。据我所知,匹配的唯一可能值是Z
. 任何其他值都会导致异常。
有什么方法可以正确设置吗?还是 Jadira 框架中的错误?