Hibernate 4 и joda-time
они счастливо женаты?
Я использую последнюю версию hibernate (4) и версии 1.3 joda-time hibernate support, которая также я считаю текущей последней версией.
Кажется, что все работает нормально (столбцы даты созданы как ожидалось) при использовании аннотаций:
@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate myDate;
Есть ли у них какие-либо известные проблемы с использованием этих версий вместе?
Обновление
Ну, получается, что столбцы создаются, но не могут заполняться никакими данными:
Обработка обработчика завершилась неудачно; Вложенное исключение - java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet
Они несовместимы, и я должен использовать usertype. См. ответ ниже.
Ответы
Ответ 1
Четкая нехватка документации означает, что мне может быть полезно записать шаги, необходимые для интеграции. Убедитесь, что ваши библиотеки обновлены.
Вам понадобится: [если у вас уже есть hibernate4]
Последняя версия joda-time
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.0</version>
</dependency>
и пользовательский тип lib
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>3.0.0.CR1</version>
</dependency>
Затем используйте следующие классы сущностей (не обязательно для LocalDateTime, может быть любой из доступных классов):
import org.joda.time.LocalDateTime;
и для определения столбца:
@Column(name="updated", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updated;
Ответ 2
Я добавлю это как отдельный ответ, поскольку это, на мой взгляд, важная информация для тех, кто обновляется до Hibernate 4, и нуждается в переходе на использование постоянных временных типов jadira. Эта страница высоко оценивается в результатах поиска google для hibernate 4 и jodatime, поэтому я добавлю ее здесь. (Отдельное обсуждение этой проблемы см.: Время Joda DateTime неправильно хранится в базе данных)
Если вы находитесь в часовом поясе, отличном от UTC, необходима важная конфигурация, чтобы получить то же поведение, что и с типом поддержки hibernate для joda-времени. То, как временные типы jadira работают по умолчанию, заключается в преобразовании всех значений в часовой пояс UTC перед сохранением базы данных и преобразовании обратно в системный часовой пояс при загрузке значений из базы данных.
Я был сожжен этим после обновления, когда у меня было много временных меток с моим точным часовым поясом в базе данных (UTC + 1 (+2 в летнее время)). При загрузке после перехода на Hibernate 4, 1 или 2 часа (в зависимости от того, была ли отметка времени в летнее время), добавлено значение в базе данных, что означает, что все существующие временные метки были представлены ошибочно. Кроме того, новые значения временной метки сохранялись в базе данных с часовым поясом UTC, что приводило их к правильному отображению в приложении, но было неправильным в базе данных. В общем, горячий беспорядок таймшонов и временных меток.
Итак, чтобы получить то же поведение, что и с поддержкой hibernate-поддержки joda-времени (время datetime сохраняется в часовом поясе рассматриваемого сервера, а метки времени в базе данных совпадают с тем, что загружается в приложение), следующие свойства должны быть добавлены в конфигурацию JPA/Hibernate (в моем случае hibernate.properties
):
jadira.usertype.autoRegisterUserTypes=true
jadira.usertype.databaseZone=jvm
jadira.usertype.javaZone=jvm
Это гарантирует, что отметки времени в базе данных будут иметь тот же часовой пояс, что и приложение, что, в свою очередь, будет часовым поясом jvm (в большинстве случаев часами сервера приложений).
Кроме того, из того, что я понимаю, autoRegisterUserTypes
-property устраняет необходимость в @Type
-nnotation для выбора общих типов, среди которых типы Jodatime DateTime
и LocalDate
.