Hibernate, сохранить предыдущее состояние объекта - PullRequest
3 голосов
/ 18 декабря 2009

Существует ли какой-либо общепринятый, проверенный на практике способ, использующий спящий режим, который ведет историю изменений сущностей в базе данных?

Нам нужно отслеживать довольно много объектов, и мы хотим иметь возможность отменить изменения в объектах.

Я пытался использовать перехватчики hibernate, но старое состояние объекта доступно только при выполнении merge(). В основном мы делаем update() или saveOrUpdate() хотя ...

В настоящее время я позволяю warp-persist вместе с Guice управлять сессией.

Ответы [ 5 ]

4 голосов
/ 18 декабря 2009

Я сделал это с помощью Interceptor (создаю свой собственный на основе EmptyInterceptor ). Мне удалось получить все изменения (объединить, сохранить, saveOrUpdate и удалить) в onFlushDirty ().

Методы EmptyInterceptor Я использовал:

@Override
public boolean onFlushDirty(Object object, Serializable id,
    Object[] newValues, Object[] oldValues, String[] properties,
    Type[] types) throws CallbackException {

@Override
public boolean onSave(Object object, Serializable id, Object[] newValues,
    String[] properties, Type[] types) throws CallbackException {

@Override
public void onDelete(Object object, Serializable id, Object[] newValues,
    String[] properties, Type[] types) throws CallbackException {

В onFlushDirty () мне нужно было запросить предыдущее состояние объекта:

Connection c = sessionFactory.getCurrentSession().connection();
Session session = sessionFactory.openSession(c);

BaseEntity newBaseEntity = (BaseEntity) object;
BaseEntity oldBaseEntity = (BaseEntity) session.get(newBaseEntity.getClass(), newBaseEntity.getId());
1 голос
/ 18 декабря 2009

Существует проект автоматического контроля версий и аудита, разработанный JBoss: envers . Я могу порекомендовать использовать это, я уже реализовывал аудит вручную, и это может стать очень грязным, когда вы начнете подходить к более сложным случаям использования.

1 голос
/ 18 декабря 2009

Hibernate Envers от JBoss, вероятно, то, что вы ищете:

Цель проекта Envers - облегчить аудит / управление версиями постоянных классов. Все, что вам нужно сделать, это аннотировать ваш постоянный класс или некоторые его свойства, которые вы хотите проверять, с помощью @Audited. Для каждого проверяемого объекта будет создана таблица, в которой будет храниться история изменений, внесенных в объект. Затем вы можете без особых усилий извлекать и запрашивать исторические данные.

1 голос
/ 18 декабря 2009

JBoss envers , возможно, то, что вы ищете.

Проект Envers направлен на обеспечение легкого аудита / управления версиями постоянных классов. Все, что вам нужно сделать, это аннотировать ваш постоянный класс или некоторые его свойства, которые вы хотите проверять, с помощью @Audited. Для каждого проверяемого объекта будет создана таблица, в которой будет храниться история изменений, внесенных в объект. Затем вы можете получить и запросить исторические данные без особых усилий.

Подобно Subversion, библиотека имеет концепцию ревизий. По сути, одна транзакция - это одна ревизия (если только транзакция не изменила какие-либо проверенные объекты). Поскольку ревизии являются глобальными и имеют номер ревизии, вы можете запрашивать различные объекты в этой ревизии, получая (частичное) представление базы данных в этой ревизии. Вы можете найти номер ревизии, имеющий дату, и наоборот, вы можете получить дату, когда ревизия была принята.
0 голосов
/ 18 декабря 2009

У меня была точно такая же проблема. Одним из способов решения этой проблемы является lock() с предыдущим состоянием, а затем merge() с новым состоянием, вместо выполнения update() только с новым состоянием.

Тогда hibernate знает о до / после и доступен в перехватчиках / прослушивателях событий.

НТН.

...