Установите время создания и обновления с помощью Hibernate в отображениях Xml - PullRequest
5 голосов
/ 14 апреля 2010

Я использую Hibernate с Xml отображениями. У меня есть объект, который имеет два поля creationDate и updateDate типа timestamp, которые должны быть заполнены текущим временем UTC, когда объект сохраняется и обновляется. Я знаю о существовании аннотаций @PrePersist и @PreUpdate, но не знаю, как использовать их эквивалент в моих сопоставлениях XML.

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

Спасибо

Ответы [ 2 ]

9 голосов
/ 14 апреля 2010

Я знаю о существовании аннотаций @PrePersist и @PreUpdate, но не знаю, как использовать их эквивалент в моих сопоставлениях Xml.

Архитектура событий Hibernate3 обеспечивает нечто эквивалентное, и вы можете зарегистрировать прослушиватели для PreInsertEvent, PreUpdateEvent или SaveOrUpdateEvent (полный список см. В пакете org.hibernate.event), чтобы установить и обновить даты создания / обновления.

Другой подход заключается в использовании перехватчика , либо Session -области или SessionFactory -области, и для установки createDate и updateDate в onSave(...), обновите updateDate в onFlushDirty(...).


Обновление: Я оставляю свои первоначальные предложения ниже, но я думаю, что правильный подход (должен был быть мой первоначальный ответ) - это использовать перехватчик или архитектуру события.

Вы можете использовать атрибут generated timestamp, чтобы получить creationDate и updateDate генерируется базой данных при вставке и при вставке и обновлении соответственно:

<class name="MyEntity" table="MY_ENTITY">
  <id .../>
  <timestamp name="createDate" generated="insert" ... />
  <timestamp name="updateDate" generated="always" ... />
  ...
</class>

Подробнее см. В разделе сгенерированные свойства .

Вариант 1

Похоже, что timestamp не поддерживает generatead, поэтому мое предложение не будет работать. Тем не менее, прочитав документацию более внимательно, я понимаю, что timestamp является альтернативой версионированию, и я не думаю, что это подходящий выбор для таких полей, как createDate и updateDate (это может сработать позже, но это не то, для чего timestamp).

Таким образом, я бы все равно использовал сгенерированные свойства , но с простыми свойствами вместо timestamp:

<class name="MyEntity" table="MY_ENTITY">
  <id .../>
  <property name="createDate" update="false" insert="false" generated="insert" ... />
  <property name="updateDate" update="false" insert="false" generated="always" ... />
  ...
</class>

На уровне базы данных для этого потребуется использовать триггер для столбца updateDate. Для столбца createDate было бы неплохо использовать что-то вроде current_timestamp в качестве значения по умолчанию. Но триггеры, возможно, не нужны ...

Вариант 2

Чтобы избежать триггера опции 1 , можно использовать вариант updateDate для управления версиями (и, следовательно, отобразить его как timestamp):

<class name="MyEntity" table="MY_ENTITY">
  <id .../>
  <timestamp name="updateDate" ... />
  <property name="createDate" update="false" insert="false" generated="insert" ... />
  ...
</class>

Тот же подход, что и в варианте 1 для createDate, используйте значение по умолчанию на уровне базы данных.

Вариант 3

Смотри верх этого ответа ...

1 голос
/ 14 апреля 2010

Метки времени в Hibernate, по-видимому, всегда обновляются автоматически при изменении сущности, поэтому вы не можете использовать отображение <timestamp> для даты создания. Однако вы можете сохранить его как простое свойство java.util.Date, инициализировав его new Date().

Для отметки времени обновления попробуйте следующее:

public class MyEntity {
  ...
  private Date updateDate;
  ...
}

<class name="MyEntity" table="MY_ENTITY">
  <id .../>
  <timestamp name="updateDate" access="field" column="UPDATE_DATE"/>
  ...
</class>

Обратите внимание, что timestamp должно идти сразу после id в отображении.

К вашему сведению, это ссылка на атрибуты timestamp .

...