In order to avoid concurrent modifications of the same managed entity, one can use a "version" field, by annotating an integer or timestamp field with the @Version annotation defined by JSR-220.
When about to merge/update such a versioned entity, the entity manager is supposed to check this version field in order to establish if the state of this entity is the last persisted one.
If it is not, a specific exception should be raised to let the caller (i.e. application developer) know that the operation could not be performed due to stale object state (a recoverable case: simply ask the user to re-edit the entity with the last persisted state...).
When using a Hibernate session, you get a StaleObjectStateException in such cases.
In my understanding, I was going to get an OptimisticLockException with a JPA entity manager.
However, when used in J2SE, the EM requires the use of an EntityTransaction.
And, unfortunately, its commit() method is not contractually allowed to throw OptimisticLockException (while the documentation for this exception states that it can be thrown while committing).
How is the caller supposed to determine the fact that the commit failed because of a concurrent modification ?
(Note: Hibernate's JPA implementation conforms to the specification and does not throw OptimisticLockException but a RollbackException whose cause is an StaleObjectStateException)
|