Взаимодействие с Hibernate Session во время вызовов событий - PullRequest
4 голосов
/ 18 февраля 2010

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

Я полагаю, что могу подключиться к модели событий гибернации и прослушать события, которые сообщают мне, когда что-то изменилось, наблюдать за любыми изменениями экземпляров интересующего меня типа объекта, а затем иметь некоторый пользовательский код, генерирующий строки истории .

Я хочу, чтобы строки истории были записаны в одной транзакции, и в идеале использовать hibernate (следовательно, используя тот же сеанс)

У меня есть несколько вопросов / проблем

  • Какие события гибернации я должен перехватить, если я хочу перехватить только изменения?
  • Как мне участвовать в том же сеансе / транзакции, что и сеанс, который генерирует события. Я прочитал, что есть проблемы, взаимодействующие с Session внутри обработчиков событий?

Любая помощь приветствуется.

Ответы [ 3 ]

2 голосов
/ 18 февраля 2010

Существует универсальное решение аудита для спящих объектов, называемое envers , которое должно сработать.

Однако, если этого решения недостаточно (как следует из вашего комментария), пакет org.hibernate.events определяет используемые события. В вашем случае я бы предложил реализовать хотя бы интерфейс PostUpdateEventListener.

1 голос
/ 03 марта 2010

При использовании этих событий убедитесь, что вы не касаетесь сеанса, который вызвал события. Получить сеанс и получить фабрику сеансов и открыть новый сеанс. Это все еще будет в той же транзакции, но вы избежите многих проблем Hibernate.

Кроме того, если вы начнете просматривать графы объектов на объекте, вызвавшем событие, то вы можете получить странные ошибки, так как вы изменили состояния коллекции во время сброса. На эту «ошибку» открыты билеты на Jira.

1 голос
/ 18 февраля 2010

События pre-insert и pre-update кажутся хорошим выбором.

Ваши PrePersistEvent и PreUpdateEvent имеют метод getSession(), который:

источник события сеанса для этого события. Это основной сеанс, из которого было сгенерировано это событие.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...