HHH-12558 Lazy load entity loaders for the less common lock modes
This commit is contained in:
parent
d5d68dcec5
commit
98cab7aefb
|
@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
@ -236,7 +237,9 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
private final Map uniqueKeyLoaders = new HashMap();
|
private final Map uniqueKeyLoaders = new HashMap();
|
||||||
private final Map lockers = new HashMap();
|
private final Map lockers = new HashMap();
|
||||||
private final Map loaders = new HashMap();
|
private UniqueEntityLoader noneLockLoader;
|
||||||
|
private UniqueEntityLoader readLockLoader;
|
||||||
|
private final Map<Object, UniqueEntityLoader> loaders = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
// SQL strings
|
// SQL strings
|
||||||
private String sqlVersionSelectString;
|
private String sqlVersionSelectString;
|
||||||
|
@ -4117,61 +4120,14 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
//Relational based Persisters should be content with this implementation
|
//Relational based Persisters should be content with this implementation
|
||||||
protected void createLoaders() {
|
protected void createLoaders() {
|
||||||
|
// We load the entity loaders for the most common lock modes.
|
||||||
|
|
||||||
|
noneLockLoader = createEntityLoader( LockMode.NONE );
|
||||||
|
readLockLoader = createEntityLoader( LockMode.READ );
|
||||||
|
|
||||||
final Map loaders = getLoaders();
|
final Map loaders = getLoaders();
|
||||||
loaders.put( LockMode.NONE, createEntityLoader( LockMode.NONE ) );
|
|
||||||
|
|
||||||
UniqueEntityLoader readLoader = createEntityLoader( LockMode.READ );
|
// The loaders for the other lock modes are lazily loaded and will later be stored in this map.
|
||||||
loaders.put( LockMode.READ, readLoader );
|
|
||||||
|
|
||||||
//TODO: inexact, what we really need to know is: are any outer joins used?
|
|
||||||
boolean disableForUpdate = getSubclassTableSpan() > 1 &&
|
|
||||||
hasSubclasses() &&
|
|
||||||
!getFactory().getDialect().supportsOuterJoinForUpdate();
|
|
||||||
|
|
||||||
loaders.put(
|
|
||||||
LockMode.UPGRADE,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.UPGRADE )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.UPGRADE_NOWAIT,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.UPGRADE_NOWAIT )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.UPGRADE_SKIPLOCKED,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.UPGRADE_SKIPLOCKED )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.FORCE,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.FORCE )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.PESSIMISTIC_READ,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.PESSIMISTIC_READ )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.PESSIMISTIC_WRITE,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.PESSIMISTIC_WRITE )
|
|
||||||
);
|
|
||||||
loaders.put(
|
|
||||||
LockMode.PESSIMISTIC_FORCE_INCREMENT,
|
|
||||||
disableForUpdate ?
|
|
||||||
readLoader :
|
|
||||||
createEntityLoader( LockMode.PESSIMISTIC_FORCE_INCREMENT )
|
|
||||||
);
|
|
||||||
loaders.put( LockMode.OPTIMISTIC, createEntityLoader( LockMode.OPTIMISTIC ) );
|
|
||||||
loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, createEntityLoader( LockMode.OPTIMISTIC_FORCE_INCREMENT ) );
|
|
||||||
|
|
||||||
loaders.put(
|
loaders.put(
|
||||||
"merge",
|
"merge",
|
||||||
|
@ -4183,6 +4139,46 @@ public abstract class AbstractEntityPersister
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UniqueEntityLoader getLoaderByLockMode(LockMode lockMode) {
|
||||||
|
if ( LockMode.NONE == lockMode ) {
|
||||||
|
return noneLockLoader;
|
||||||
|
}
|
||||||
|
else if ( LockMode.READ == lockMode ) {
|
||||||
|
return readLockLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loaders.computeIfAbsent( lockMode, this::createLazyLoadedEntityLoader );
|
||||||
|
}
|
||||||
|
|
||||||
|
private UniqueEntityLoader createLazyLoadedEntityLoader(Object lockModeObject) {
|
||||||
|
// Unfortunately, the loaders map mixes LockModes and Strings as keys so we need to accept an Object.
|
||||||
|
// The cast is safe as we will always call this method with a LockMode.
|
||||||
|
LockMode lockMode = (LockMode) lockModeObject;
|
||||||
|
|
||||||
|
switch ( lockMode ) {
|
||||||
|
case NONE:
|
||||||
|
case READ:
|
||||||
|
case OPTIMISTIC:
|
||||||
|
case OPTIMISTIC_FORCE_INCREMENT:
|
||||||
|
return createEntityLoader( lockMode );
|
||||||
|
case UPGRADE:
|
||||||
|
case UPGRADE_NOWAIT:
|
||||||
|
case UPGRADE_SKIPLOCKED:
|
||||||
|
case FORCE:
|
||||||
|
case PESSIMISTIC_READ:
|
||||||
|
case PESSIMISTIC_WRITE:
|
||||||
|
case PESSIMISTIC_FORCE_INCREMENT:
|
||||||
|
//TODO: inexact, what we really need to know is: are any outer joins used?
|
||||||
|
boolean disableForUpdate = getSubclassTableSpan() > 1 &&
|
||||||
|
hasSubclasses() &&
|
||||||
|
!getFactory().getDialect().supportsOuterJoinForUpdate();
|
||||||
|
|
||||||
|
return disableForUpdate ? readLockLoader : createEntityLoader( lockMode );
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException( String.format( "Lock mode %1$s not supported by entity loaders.", lockMode ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void createQueryLoader() {
|
protected void createQueryLoader() {
|
||||||
if ( loaderName != null ) {
|
if ( loaderName != null ) {
|
||||||
queryLoader = new NamedQueryLoader( loaderName, this );
|
queryLoader = new NamedQueryLoader( loaderName, this );
|
||||||
|
@ -4276,7 +4272,7 @@ public abstract class AbstractEntityPersister
|
||||||
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
|
return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (UniqueEntityLoader) getLoaders().get( lockOptions.getLockMode() );
|
return (UniqueEntityLoader) getLoaderByLockMode( lockOptions.getLockMode() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue