问题
I have 2 entities: Parent
and Child
in a one-to-many relationship. The Parent
is versioned, i.e. has a @Version field. My goal is to synchronize changes to both Parent
and Child
entities on the Parent
's version.
E.g. one thread updates the Parent
and another one updates one of it's Child
s, this should cause an OptimisticLockException.
Is it possible?
I tried adding a @PreUpdate to the Child
which would increment the version of it's Parent
, but that didn't help because Hibernate seems to execute listeners only after it checks versions so the transaction commits successfully anyway.
If it is possible, how can it be implemented?
回答1:
Did you try making the Child a component instead of an entity?
The default Hibernate operations might be much more aligned with your requirements. The idea is that the Parent is a real entity, while the Child is considered an element of a bigger whole.
In Hibernate, this should be considered the default parent-child relationship. Parent-Child relation between entities are less natural, although possible.
回答2:
First of all, there are two issues here that need to be clarified:
I take it you're trying to catch updates made to a particular Child instance rather than collection modifications (e.g. new Child being added / old removed). The latter will increment parent's version by default.
When you say "one thread updates Parent" and "another updates Child" I'm assuming that changes are immediately flushed. In other words, the sequence of events is: parent is updated and persisted (changes flushed; transaction committed1); another thread tries to update child which points to the previous version of parent and fails. If that's not the case, optimistic locking is not going to help you.
1 You may be able to work around the "transaction committed" bit by setting appropriate isolation level, but that's likely to cause more problems then it solves in concurrent environment. You can't work around "immediate flush" requirement.
Assuming the above assumptions are correct, you'll need to use EntityManager.lock() method to lock Parent prior to updating your Child instance. See LockModeType and Hibernate EntityManager docs for details.
来源:https://stackoverflow.com/questions/1399679/can-hibernates-version-consider-changes-in-related-entities