Я пытаюсь сохранить java.time.LocalDateTime
используя Hibernate и JPA. Я использовал Jadira Framework («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
(почти) правильно.Как настроить jadira PersistentLocalDateTime с java.time.LocalDateTime?
Единственная проблема заключается в том, что значения в базе данных составляют +2 часа до правильного значения времени из полей в Java. Я в CEST (UTC + 2), поэтому понял, что это проблема с часовыми поясами. Я отлаживал код PersistentLocalDateTime
, и это то, что я нашел.
PersistentLocalDateTime
используетorg.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
AbstractTimestampThreeTenColumnMapper
имеет полеZoneOffset databaseZone
по умолчанию установлен вZoneOffset.of("Z")
(UTC).- Поскольку я думаю, что моя база данных находится в часовом поясе UTC (и приложение находится в UTC + 2), он добавляет два часа к моему времени во время преобразования в базу данных (и вычитает два часа с моего времени во время преобразования из базы данных). Поэтому в приложении я вижу правильную дату и время, но в базе данных я не являюсь.
Я обнаружил, что можно добавить параметры @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
и java.util.TimeZone
не совпадают. Насколько я вижу, единственное возможное значение, которое соответствует Z
. Любые другие значения приводят к исключениям.
Есть ли способ установить это правильно? Или это ошибка в Jadira Framework?
Такое поведение адресуется 5.0.0.GA, отображающая через ZoneId. Отказ от ответственности: Я поддерживаю Джадиру. –