我有两个实体:Parent
和Child
,一对多关系。 Parent
是版本化的,即具有@Version字段。我的目标是将更改同步到Parent
版本上的Child
和Parent
实体。
E.g。一个线程更新Parent
,另一个更新其中一个Child
,这应该导致一个OptimisticLockException。
有可能吗?
我尝试将@PreUpdate添加到Child
,这将增加它的Parent
版本,但这没有帮助,因为Hibernate似乎只在检查版本后才执行侦听器,因此事务提交无论如何都成功了。
如果有可能,如何实施?
答案 0 :(得分:1)
您是否尝试让儿童成为组件而非实体?
默认的Hibernate操作可能更符合您的要求。这个想法是父母是一个真实的实体,而儿童被认为是一个更大整体的元素。
在Hibernate中,这应该被视为默认的父子关系。 尽管可能,实体之间的父子关系不太自然。
答案 1 :(得分:1)
首先,这里有两个问题需要澄清:
我认为你试图捕获对特定Child实例的更新,而不是集合修改(例如,添加/旧的Child被删除)。后者默认会增加父版本。
当您说“一个线程更新父级”和“另一个更新子级”时,我假设立即刷新更改。换句话说,事件序列是:父更新和持久(更改已刷新;事务已提交 1 );另一个线程尝试更新指向父项的先前版本的子项并失败。如果情况并非如此,乐观锁定对您没有帮助。
1 您可以通过设置适当的隔离级别来解决“事务已提交”位,但这可能会导致更多问题,然后在并发环境中解决。你不能解决“立即冲洗”的要求。
假设上述假设是正确的,您需要在更新Child实例之前使用EntityManager.lock()方法锁定 Parent 。有关详细信息,请参阅LockModeType和Hibernate EntityManager docs。