artemb
artemb

Reputation: 9371

Can Hibernate's @Version consider changes in related entities?

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 Childs, 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?

Upvotes: 3

Views: 1782

Answers (2)

ChssPly76
ChssPly76

Reputation: 100706

First of all, there are two issues here that need to be clarified:

  1. 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.

  2. 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.

Upvotes: 1

KLE
KLE

Reputation: 24159

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.

Upvotes: 1

Related Questions