#java #hibernate #concurrency #versioning
#java #спящий режим #параллелизм #управление версиями
Вопрос:
Я использую режим гибернации со столбцом версии для реализации оптимального управления параллелизмом.
Вопрос: Возможно ли увеличивать номер версии объекта каждый раз, когда я сохраняю его в базе данных, независимо от того, был ли он изменен или нет?
До тех пор, пока в объекте изменяется какое-либо поле, номер версии увеличивается. Но, если ни одно поле в объекте не изменилось, номер версии объекта остается неизменным.
Причина этого вопроса в том, что у меня есть логическая связь master-detail между двумя таблицами, и я хотел бы увеличивать номер версии в главной таблице всякий раз, когда что-то меняется в деталях, даже если основные данные не изменились. Эта взаимосвязь master-detail не отображается в режиме гибернации. Я просто всегда сохраняю их вместе в одной транзакции.
Комментарии:
1. Рассматривали ли вы возможность использования перехватчиков для запуска обновления версии?
2. Я еще не работал с перехватчиками. У вас есть пример? Насколько я понимаю, может быть достаточно пометить объект как загрязненный, перезаписав функцию findDirty(…) .
3. Я использовал их в основном для целей аудита, но они предоставляют вам доступ к объектам после различных событий (например, postFlush, postFlushDirty и т.д.). Когда информация сброшена, у вас может быть второй вызов, который обновляет номер версии на главном сервере.
Ответ №1:
Вы можете использовать перехватчики режима гибернации для обновления номера версии основной записи, когда вы определяете, что деталь изменилась.
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/events.html
Одним из ограничений является то, что это решение специфично для режима гибернации. JPA также допускает управляемую событиями логику с использованием аннотаций (например, postPersist, PostUpdate и т.д.), Но эти методы не дают вам доступа к базовому сеансу (и, что более важно, документация предостерегает вас от использования этих методов для изменения данных сеанса). Обычно я использовал перехватчики для выполнения аудита, но их можно легко расширить, чтобы обновить номер версии при изменении записи.
Ответ №2:
Вы можете вызвать lock()
(или использовать другие методы, которые принимают LockMode
) с LockMode.OPTIMISTIC_FORCE_INCREMENT
помощью.
Комментарии:
1. По этому поводу существует открытая проблема ( opensource.atlassian.com/projects/hibernate/browse/HHH-5222 и посмотрите также его предшественник 5032, который утверждает, что исправлен), но я все равно проверю его.
2. Я проверил ваше предложение, но, к сожалению, оно не работает из-за той же ошибки, упомянутой в проблеме JIRA выше.
3. Эта статья: thorben-janssen.com/… … предлагает также LockModeType . OPTIMISTIC_FORCE_INCREMENT.