2012-01-23 2 views
62

они счастливо замужем?hibernate 4 и joda-time

Я использую самую последнюю версию hibernate (4) и версию 1.3 от joda-time hibernate support, которая также я считаю нынешней последней версией.

Все, кажется, работает OK (дата столбцы, созданные, как и ожидалось) при использовании аннотаций:

@Column 
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate") 
private LocalDate myDate; 

являются их любые известные проблемы, связанные с использованием этих версий вместе?

Update Ну получается, столбцы получить созданы, но не может заполнить любые данные:

обработка Handler не удался; вложенное исключение составляет java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet

Они несовместимы, и я должен использовать usertype. См. Ответ ниже.

+0

Вы только что сказали нам, что они * работали вместе, не так ли? – skaffman

+0

@skaffman Я не тестировал ничего, кроме создания столбцов ... По моему мнению, предыдущие версии (joda-time lib) пришлось перекомпилировать против более новой версии спящего режима. Это вызвало тревогу - отсюда и вопрос ... – NimChimpsky

+0

Они не счастливы в браке, спящий имеет другие отношения ... и joda ..:/.. Она болит – nobalG

ответ

96

Относительно нехватка документации, это может быть полезно для меня записать шаги, необходимые для интеграции. Убедитесь, что ваши библиотеки обновлены.

Вам понадобятся: [если вы уже hibernate4]

Последняя версия Joda времени

<dependency> 
    <groupId>joda-time</groupId> 
    <artifactId>joda-time</artifactId> 
    <version>2.0</version> 
</dependency> 

и UserType 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; 
+1

Как мы узнаем, к какому типу он относится к нашей базе данных? – benstpierre

+0

@Benju взгляните на таблицу базы данных после ее создания ... – NimChimpsky

+0

Правильно, поэтому используйте автоматическую генерацию таблиц и посмотрите на результат? – benstpierre

29

Я добавлю это как отдельный ответ, так как это, по-моему важная информация для тех, кто обновляемом в спящий режим 4, и в случае необходимости перенастройки с использованием постоянных временных типов jadira в , Эта страница высоко оценивается в результатах поиска google для hibernate 4 и jodatime, поэтому я добавлю ее здесь. (Отдельное обсуждение этого вопроса см. В: Joda time DateTime incorrectly stores in database)

Если вы находитесь в часовом поясе, отличном от UTC, необходима важная конфигурация, чтобы получить такое же поведение, как и с hibernate joda-time тип поддержки. То, как временные типы jadira работают по умолчанию, заключается в преобразовании всех значений в часовой пояс UTC до того, как они будут сохраняться в базе данных, и при обращении к часовому поясу системы при загрузке значений из базы данных.

Я был сожжен этим после обновления, когда у меня было много временных меток с моим точным часовым поясом в базе данных (UTC + 1 (+2 в летнее время)). При загрузке после перехода на Hibernate 4, 1 или 2 часа (в зависимости от того, была ли отметка времени в летнее время), добавлено значение в базе данных, что означает, что все существующие временные метки были представлены ошибочно. Кроме того, новые значения временной метки сохранялись в базе данных с часовым поясом UTC, что приводило их к правильному отображению в приложении, но было неправильным в базе данных.В общем, горячий беспорядок таймшонов и временных меток.

Итак, чтобы получить то же поведение, что и с поддержкой hibernate-поддержки joda-времени (время существования сохраняется в часовом поясе рассматриваемого сервера, а метки времени в базе данных такие же, как и то, что загружается в приложение), следующие свойства должны быть добавлены к конфигурации JPA/Hibernate (в моем случае, hibernate.properties):

jadira.usertype.autoRegisterUserTypes=true 
jadira.usertype.databaseZone=jvm 
jadira.usertype.javaZone=jvm 

Это позволит убедиться, что временные метки в базе данных будут иметь тот же часовой пояс, что и приложения, которое, в свою очередь, будет часовым поясом jvm (в большинстве случаев часами сервера приложений).

Кроме того, от того, что я понимаю, autoRegisterUserTypes -property устраняет необходимость @Type -annotation для выбора общих видов, среди них Jodatime-типов DateTime и LocalDate.

+2

Поскольку вы решили свою проблему, и это не было напрямую связано с этим вопросом, я удалю свои комментарии и пометьте ваши данные для удаления, поэтому мы сохраним раздел комментария чистым и точным. – Tobb

+0

Просто вопрос в сторону: почему бы не хранить каждую метку времени в UTC? Что делать, если сервер переходит в другой часовой пояс? Imho было бы лучше хранить все временные метки в UTC и позволить клиенту решить, в каком часовом поясе он находится. – displayname

+0

Как правило, я бы согласился. В моем случае, однако, не было никаких шансов, что сервер будет перемещен в другой часовой пояс. Кроме того, проблема здесь в том, что поведение по умолчанию меняется, в моем случае, без моего ведома. Поэтому, когда вы не знаете, что это происходит, вы не можете перенести свои данные и в итоге установить набор временных меток с разными часовыми поясами, что, конечно, не очень хорошо. Но если это имеет смысл для вашего проекта, вы можете пропустить приведенную здесь настройку и вместо этого перенести свою базу данных. Одна вещь, которая отрицательно относится ко всему UTC, заключается в том, что отчеты SQL становятся либо сложными, либо неправильными. – Tobb

Смежные вопросы