The following steps involving update of an entity with a Version property in a transaction result in an OptimisticLockException during commit.
Employee e = entityManager.find(Employee.class, THE_KEY_HERE);
Update some property of the entity (and merge)
The problem here is that an EntityVerifyVersionProcess is registered with the EntityEntry associated with the entity at the time that the entity is locked.
Later, when the entity is refreshed, that EntityEntry is replaced by a new one in the PersistenceContext. This makes the EntityEntry registered with the EntityVerifyVersionProcess stale.
After the updated entity is pushed to the database by EntityUpdateAction#execute, which calls EntityEntry#postUpdate to update the version in the entity and the current EntityEntry.
Later, when EntityVerifyVersionProcess#doBeforeTransactionCompletion executes using the stale EntityEntry, OptimisticLockException is thrown because the version in the stale EntityEntry does not match the current version.
lock the entity when it is refreshed; i.e., entityManager.refresh(entity, LockModeType.READ);
refresh the entity first, then lock it.
Fixed in master branch.
Fixed in 5.3 branch as well.