2009-09-09 2 views
3

У меня есть 2 объекта: Parent и Child в отношениях один-ко-многим. Parent имеет версию, то есть имеет поле @Version. Моя цель - синхронизировать изменения как с объектами Parent, так и с Child на версии Parent.Может ли Xibernate's @Version рассматривать изменения в связанных объектах?

E.g. один поток обновляет Parent, а другой обновляет один из его Child s, это должно вызвать исключение OptimisticLockException.

Возможно ли это?

Я попытался добавить @PreUpdate к Child которая увеличит его версию это Parent, но это не помогло, потому что Hibernate кажется выполнить слушатель только после того, как он проверяет версию, так что транзакции успешно в любом случае.

Если возможно, то как оно может быть реализовано?

ответ

1

Вы попробовали сделать ребенка компонентом вместо субъектом?

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

В Hibernate это следует рассматривать как отношения родитель-потомок по умолчанию. Родительские отношения между субъектами менее естественны, хотя и возможны.

+0

Я думаю, что это не вариант для меня. Ребенок - это первоклассный объект с его идентификатором и состоянием, и он должен оставаться таким. Хотя ваша идея определенно является решением, она не применима для меня. – artemb

+0

Хорошо, я понимаю. , ,Ваше требование может быть возможно с Hibernate, но я не помню, что вы должны попробовать ... извините. – KLE

1

Прежде всего, существуют две проблемы, которые необходимо уточнить:

  1. Я понимаю, что вы пытаетесь поймать обновления, сделанные в конкретном случае ребенка, а не модификации коллекции (например, нового ребенка добавлен/старый удален). Последний по умолчанию увеличит родительскую версию.

  2. Когда вы говорите, что «один поток обновляет родительский» и «другой обновляет ребенка», я предполагаю, что изменения сразу же очищаются. Другими словами, последовательность событий: родительский обновляется и сохраняется (изменения покрашены, совершено транзакция); другой поток пытается обновить дочерний элемент, который указывает на предыдущую версию родителя и терпит неудачу. Если это не так, оптимистическая блокировка не поможет вам.

Вы можете быть в состоянии работать вокруг «сделки, совершенные» бит, установив соответствующий уровень изоляции, но это, вероятно, вызовет больше проблем, то он решает в параллельной среде. Вы не можете обойти требование «немедленного флеша».

Предполагая, что приведенные выше допущения верны, вам необходимо использовать метод EntityManager.lock() для блокировки Родитель перед обновлением экземпляра Child. См. LockModeType и Hibernate EntityManager docs.

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

  • Нет связанных вопросов^_^