users@glassfish.java.net

Re: JPA optimistic locking inconsistency

From: <glassfish_at_javadesktop.org>
Date: Fri, 26 Oct 2007 06:15:13 PDT

Based on your description what i actually happening here is in the first ase you are attempting to perform an em.merge(). For any number of reasons (refresh, instance wasn't in the cache when it was loaded) the managed instance in the PersistenceContext and the cached version already contain a newer version than the object instance you are attempting to merge. On merge JPA requires that the version of the merging object be checked against the managed version and OptimisticLockException thrown if the versions differ. After the exception you are seeing the updated version because it was already there.

In the second case the updated version in not managed in the PersistenceContext so the merge passes the version check. On Commit the version numbers are checked against the database and an OptimisticLockException is thrown by TopLink and wrapped in a TransactionRollbackException as required by the specification. TopLink does not automatically refresh the data in the cache in this case because when the exception is generated by TopLink TopLink is still in the transaction and could be accessing uncommitted data. An enhancement should be added to have TopLink invalidate that instance in the cache though.

You can never prevent all optimisic lock exceptions in a concurrent system but if the tolerance in your application is low you can use em.refresh() before the merge.

Aso by using em.flush() you can force the OptimisticLockException to occur within your business code instead of at the end of the transaction.
--Gordon
[Message sent by forum member 'gyorke' (gyorke)]

http://forums.java.net/jive/thread.jspa?messageID=242354