HHH-13492 : OptimisticLockException after locking, refreshing, and updating an entity
This commit is contained in:
parent
f59fe419a5
commit
d5ea37d779
|
@ -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 );
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue