HHH-13492 : OptimisticLockException after locking, refreshing, and updating an entity

This commit is contained in:
Gail Badner 2019-07-23 21:11:18 -07:00 committed by gbadner
parent f59fe419a5
commit d5ea37d779
5 changed files with 16 additions and 18 deletions

View File

@ -19,17 +19,14 @@ import org.hibernate.persister.entity.EntityPersister;
*/
public class EntityIncrementVersionProcess implements BeforeTransactionCompletionProcess {
private final Object object;
private final EntityEntry entry;
/**
* Constructs an EntityIncrementVersionProcess for the given entity.
*
* @param object The entity instance
* @param entry The entity's EntityEntry reference
*/
public EntityIncrementVersionProcess(Object object, EntityEntry entry) {
public EntityIncrementVersionProcess(Object object) {
this.object = object;
this.entry = entry;
}
/**
@ -39,6 +36,12 @@ public class EntityIncrementVersionProcess implements BeforeTransactionCompletio
*/
@Override
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityEntry entry = session.getPersistenceContext().getEntry( object );
// Don't increment version for an entity that is not in the PersistenceContext;
if ( entry == null ) {
return;
}
final EntityPersister persister = entry.getPersister();
final Object nextVersion = persister.forceVersionIncrement( entry.getId(), entry.getVersion(), session );
entry.forceLocked( object, nextVersion );

View File

@ -21,28 +21,25 @@ import org.hibernate.pretty.MessageHelper;
*/
public class EntityVerifyVersionProcess implements BeforeTransactionCompletionProcess {
private final Object object;
private final EntityEntry entry;
/**
* Constructs an EntityVerifyVersionProcess
*
* @param object The entity instance
* @param entry The entity's referenced EntityEntry
*/
public EntityVerifyVersionProcess(Object object, EntityEntry entry) {
public EntityVerifyVersionProcess(Object object) {
this.object = object;
this.entry = entry;
}
@Override
public void doBeforeTransactionCompletion(SessionImplementor session) {
final EntityPersister persister = entry.getPersister();
if ( !entry.isExistsInDatabase() ) {
// HHH-9419: We cannot check for a version of an entry we ourselves deleted
final EntityEntry entry = session.getPersistenceContext().getEntry( object );
// Don't check version for an entity that is not in the PersistenceContext;
if ( entry == null ) {
return;
}
final EntityPersister persister = entry.getPersister();
final Object latestVersion = persister.getCurrentVersion( entry.getId(), session );
if ( !entry.getVersion().equals( latestVersion ) ) {
throw new OptimisticLockException(

View File

@ -50,7 +50,7 @@ public class OptimisticForceIncrementLockingStrategy implements LockingStrategy
}
final EntityEntry entry = session.getPersistenceContextInternal().getEntry( object );
// Register the EntityIncrementVersionProcess action to run just prior to transaction commit.
( (EventSource) session ).getActionQueue().registerProcess( new EntityIncrementVersionProcess( object, entry ) );
( (EventSource) session ).getActionQueue().registerProcess( new EntityIncrementVersionProcess( object ) );
}
protected LockMode getLockMode() {

View File

@ -12,7 +12,6 @@ import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.OptimisticLockException;
import org.hibernate.action.internal.EntityVerifyVersionProcess;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.spi.EventSource;
import org.hibernate.persister.entity.Lockable;
@ -49,9 +48,8 @@ public class OptimisticLockingStrategy implements LockingStrategy {
if ( !lockable.isVersioned() ) {
throw new OptimisticLockException( object, "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
}
final EntityEntry entry = session.getPersistenceContextInternal().getEntry( object );
// Register the EntityVerifyVersionProcess action to run just prior to transaction commit.
( (EventSource) session ).getActionQueue().registerProcess( new EntityVerifyVersionProcess( object, entry ) );
( (EventSource) session ).getActionQueue().registerProcess( new EntityVerifyVersionProcess( object ) );
}
protected LockMode getLockMode() {

View File

@ -59,11 +59,11 @@ public class DefaultPostLoadEventListener implements PostLoadEventListener, Call
entry.forceLocked( entity, nextVersion );
}
else if ( LockMode.OPTIMISTIC_FORCE_INCREMENT.equals( lockMode ) ) {
final EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess( entity, entry );
final EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess( entity );
session.getActionQueue().registerProcess( incrementVersion );
}
else if ( LockMode.OPTIMISTIC.equals( lockMode ) ) {
final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess( entity, entry );
final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess( entity );
session.getActionQueue().registerProcess( verifyVersion );
}