This is an extract of what you can find in the JPA specification regarding OptimisticLockException
:
- the version check is done when writing changes to DB, hence the exception
will normally be thrown at commit time
- it always causes the transaction to be marked for rollback
- if you want to catch and handle the exception, call flush() to force DB
writes to occur earlier
- the exception provides an API to return the object that caused the exception
- it is typically handled by refreshing/reloading stale objects and retrying the transaction
For the sake of completeness, here is a copy of the relevant section from the specification:
(I cannot provide a specific link, as the document is only available in .pdf format here).
3.4.5 OptimisticLockException
Provider implementations may defer writing to the database until the end of the transaction, when consistent with the lock mode and flush mode settings in effect. In this case, an optimistic lock check may not occur until commit time, and the OptimisticLockException may be thrown in the "before completion" phase of the commit. If the OptimisticLockException must be caught or handled by the application, the flush method should be used by the application to force the database writes to occur. This will allow the application to catch and handle optimistic lock exceptions.
The OptimisticLockException provides an API to return the object that caused the exception to be thrown. The object reference is not guaranteed to be present every time the exception is thrown but should be provided whenever the persistence provider can supply it. Applications cannot rely upon this object being available.
In some cases an OptimisticLockException will be thrown and wrapped by another exception, such as a RemoteException, when VM boundaries are crossed. Entities that may be referenced in wrapped exceptions should implement Serializable so that marshalling will not fail.
An OptimisticLockException always causes the transaction to be marked for rollback.
Refreshing objects or reloading objects in a new transaction context and then retrying the transaction is a potential response to an OptimisticLockException.