HHH-17037 Changes for Hibernate Reactive
Make it possible to override the SingleIdLoadPlan and the SingleIdEntityLoader.
This commit is contained in:
parent
000e21dad5
commit
df88fd15fa
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.loader.ast.internal;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -29,20 +30,36 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
private final EnumMap<LockMode, SingleIdLoadPlan<T>> selectByLockMode = new EnumMap<>( LockMode.class );
|
||||
private EnumMap<CascadingFetchProfile, SingleIdLoadPlan<T>> selectByInternalCascadeProfile;
|
||||
|
||||
private final BiFunction<LockOptions, LoadQueryInfluencers, SingleIdLoadPlan<T>> loadPlanCreator;
|
||||
|
||||
public SingleIdEntityLoaderStandardImpl(
|
||||
EntityMappingType entityDescriptor,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this(
|
||||
entityDescriptor,
|
||||
sessionFactory,
|
||||
(lockOptions, influencers) -> createLoadPlan( entityDescriptor, lockOptions, influencers, sessionFactory )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate Reactive.
|
||||
* <p>
|
||||
* Hibernate Reactive needs to be able to override the LoadPlan.
|
||||
* </p>
|
||||
*/
|
||||
protected SingleIdEntityLoaderStandardImpl(
|
||||
EntityMappingType entityDescriptor,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
BiFunction<LockOptions, LoadQueryInfluencers, SingleIdLoadPlan<T>> loadPlanCreator) {
|
||||
// todo (6.0) : consider creating a base AST and "cloning" it
|
||||
super( entityDescriptor, sessionFactory );
|
||||
this.loadPlanCreator = loadPlanCreator;
|
||||
// see org.hibernate.persister.entity.AbstractEntityPersister#createLoaders
|
||||
// we should preload a few - maybe LockMode.NONE and LockMode.READ
|
||||
final LockOptions lockOptions = LockOptions.NONE;
|
||||
final LoadQueryInfluencers influencers = new LoadQueryInfluencers( sessionFactory );
|
||||
final SingleIdLoadPlan<T> plan = createLoadPlan(
|
||||
lockOptions,
|
||||
influencers,
|
||||
sessionFactory
|
||||
);
|
||||
final SingleIdLoadPlan<T> plan = loadPlanCreator.apply( LockOptions.NONE, influencers );
|
||||
if ( isLoadPlanReusable( lockOptions, influencers ) ) {
|
||||
selectByLockMode.put( lockOptions.getLockMode(), plan );
|
||||
}
|
||||
|
@ -83,7 +100,7 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
// This case is special because the filters need to be applied in order to
|
||||
// properly restrict the SQL/JDBC results. For this reason it has higher
|
||||
// precedence than even "internal" fetch profiles.
|
||||
return createLoadPlan( lockOptions, loadQueryInfluencers, sessionFactory );
|
||||
return loadPlanCreator.apply( lockOptions, loadQueryInfluencers );
|
||||
}
|
||||
else if ( loadQueryInfluencers.hasEnabledCascadingFetchProfile()
|
||||
&& LockMode.WRITE.greaterThan( lockOptions.getLockMode() ) ) {
|
||||
|
@ -115,17 +132,13 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
return existing;
|
||||
}
|
||||
else {
|
||||
final SingleIdLoadPlan<T> plan = createLoadPlan(
|
||||
lockOptions,
|
||||
loadQueryInfluencers,
|
||||
sessionFactory
|
||||
);
|
||||
final SingleIdLoadPlan<T> plan = loadPlanCreator.apply( lockOptions, loadQueryInfluencers );
|
||||
selectByLockMode.put( lockOptions.getLockMode(), plan );
|
||||
return plan;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return createLoadPlan( lockOptions, loadQueryInfluencers, sessionFactory );
|
||||
return loadPlanCreator.apply( lockOptions, loadQueryInfluencers );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,11 +161,7 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
}
|
||||
}
|
||||
|
||||
final SingleIdLoadPlan<T> plan = createLoadPlan(
|
||||
lockOptions,
|
||||
loadQueryInfluencers,
|
||||
sessionFactory
|
||||
);
|
||||
final SingleIdLoadPlan<T> plan = loadPlanCreator.apply( lockOptions, loadQueryInfluencers );
|
||||
selectByInternalCascadeProfile.put( fetchProfile, plan );
|
||||
return plan;
|
||||
}
|
||||
|
@ -163,17 +172,18 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
&& !getLoadable().isAffectedByEnabledFetchProfiles( loadQueryInfluencers );
|
||||
}
|
||||
|
||||
private SingleIdLoadPlan<T> createLoadPlan(
|
||||
private static <T> SingleIdLoadPlan<T> createLoadPlan(
|
||||
EntityMappingType loadable,
|
||||
LockOptions lockOptions,
|
||||
LoadQueryInfluencers queryInfluencers,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
|
||||
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
|
||||
final SelectStatement sqlAst = LoaderSelectBuilder.createSelect(
|
||||
getLoadable(),
|
||||
loadable,
|
||||
// null here means to select everything
|
||||
null,
|
||||
getLoadable().getIdentifierMapping(),
|
||||
loadable.getIdentifierMapping(),
|
||||
null,
|
||||
1,
|
||||
queryInfluencers,
|
||||
|
@ -182,8 +192,8 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
|
|||
sessionFactory
|
||||
);
|
||||
return new SingleIdLoadPlan<>(
|
||||
getLoadable(),
|
||||
getLoadable().getIdentifierMapping(),
|
||||
loadable,
|
||||
loadable.getIdentifierMapping(),
|
||||
sqlAst,
|
||||
jdbcParametersBuilder.build(),
|
||||
lockOptions,
|
||||
|
|
|
@ -613,10 +613,10 @@ public abstract class AbstractCollectionPersister
|
|||
public void postInstantiate() throws MappingException {
|
||||
if ( hasNamedQueryLoader() ) {
|
||||
// We pass null as metamodel because we did the initialization during construction already
|
||||
collectionLoader = new CollectionLoaderNamedQuery( this, getNamedQueryMemento( null ) );
|
||||
collectionLoader = createNamedQueryCollectionLoader( this, getNamedQueryMemento( null ) );
|
||||
}
|
||||
else {
|
||||
collectionLoader = createCollectionLoader( new LoadQueryInfluencers( factory ) );
|
||||
collectionLoader = createNamedQueryCollectionLoader( new LoadQueryInfluencers( factory ) );
|
||||
}
|
||||
|
||||
if ( attributeMapping.getIndexDescriptor() != null ) {
|
||||
|
@ -720,7 +720,7 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
|
||||
return attributeMapping.isAffectedByInfluencers( influencers )
|
||||
? createCollectionLoader( influencers )
|
||||
? createNamedQueryCollectionLoader( influencers )
|
||||
: getCollectionLoader();
|
||||
}
|
||||
|
||||
|
@ -765,7 +765,7 @@ public abstract class AbstractCollectionPersister
|
|||
// return attributeMapping.isNotAffectedByInfluencers( loadQueryInfluencers );
|
||||
// }
|
||||
|
||||
private CollectionLoader createCollectionLoader(LoadQueryInfluencers loadQueryInfluencers) {
|
||||
private CollectionLoader createNamedQueryCollectionLoader(LoadQueryInfluencers loadQueryInfluencers) {
|
||||
if ( loadQueryInfluencers.effectivelyBatchLoadable( this ) ) {
|
||||
final int batchSize = loadQueryInfluencers.effectiveBatchSize( this );
|
||||
return factory.getServiceRegistry()
|
||||
|
@ -773,10 +773,24 @@ public abstract class AbstractCollectionPersister
|
|||
.createCollectionBatchLoader( batchSize, loadQueryInfluencers, attributeMapping, factory );
|
||||
}
|
||||
else {
|
||||
return new CollectionLoaderSingleKey( attributeMapping, loadQueryInfluencers, factory );
|
||||
return createSingleKeyCollectionLoader( loadQueryInfluencers );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate Reactive
|
||||
*/
|
||||
protected CollectionLoader createNamedQueryCollectionLoader(CollectionPersister persister, NamedQueryMemento namedQueryMemento) {
|
||||
return new CollectionLoaderNamedQuery(persister, namedQueryMemento);
|
||||
}
|
||||
|
||||
/**
|
||||
* For Hibernate Reactive
|
||||
*/
|
||||
protected CollectionLoader createSingleKeyCollectionLoader(LoadQueryInfluencers loadQueryInfluencers) {
|
||||
return new CollectionLoaderSingleKey( attributeMapping, loadQueryInfluencers, factory );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionDataAccess getCacheAccessStrategy() {
|
||||
return cacheAccessStrategy;
|
||||
|
|
|
@ -78,7 +78,6 @@ import org.hibernate.engine.internal.MutableEntityEntryFactory;
|
|||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||
import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.profile.internal.FetchProfileAffectee;
|
||||
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
|
@ -831,7 +830,19 @@ public abstract class AbstractEntityPersister
|
|||
return memento;
|
||||
}
|
||||
|
||||
private SingleIdEntityLoader<?> createSingleIdEntityLoader(LoadQueryInfluencers loadQueryInfluencers) {
|
||||
/**
|
||||
* For Hibernate Reactive
|
||||
*/
|
||||
protected SingleIdEntityLoader<?> buildSingleIdEntityLoader() {
|
||||
if ( hasNamedQueryLoader() ) {
|
||||
// We must resolve the named query on-demand through the boot model because it isn't initialized yet
|
||||
final NamedQueryMemento memento = getNamedQueryMemento( null );
|
||||
return new SingleIdEntityLoaderProvidedQueryImpl<>( this, memento );
|
||||
}
|
||||
return buildSingleIdEntityLoader( new LoadQueryInfluencers( factory ) );
|
||||
}
|
||||
|
||||
private SingleIdEntityLoader<?> buildSingleIdEntityLoader(LoadQueryInfluencers loadQueryInfluencers) {
|
||||
if ( loadQueryInfluencers.effectivelyBatchLoadable( this ) ) {
|
||||
final int batchSize = loadQueryInfluencers.effectiveBatchSize( this );
|
||||
return factory.getServiceRegistry()
|
||||
|
@ -864,7 +875,7 @@ public abstract class AbstractEntityPersister
|
|||
return entityNameByTableNameMap;
|
||||
}
|
||||
|
||||
private MultiIdEntityLoader<Object> buildMultiIdLoader() {
|
||||
protected MultiIdEntityLoader<Object> buildMultiIdLoader() {
|
||||
if ( getIdentifierType() instanceof BasicType
|
||||
&& supportsSqlArrayType( factory.getJdbcServices().getDialect() ) ) {
|
||||
return new MultiIdEntityLoaderArrayParam<>( this, factory );
|
||||
|
@ -3588,14 +3599,8 @@ public abstract class AbstractEntityPersister
|
|||
@Override
|
||||
public final void postInstantiate() throws MappingException {
|
||||
doLateInit();
|
||||
if ( hasNamedQueryLoader() ) {
|
||||
// We must resolve the named query on-demand through the boot model because it isn't initialized yet
|
||||
final NamedQueryMemento memento = getNamedQueryMemento( null );
|
||||
singleIdLoader = new SingleIdEntityLoaderProvidedQueryImpl<>( this, memento );
|
||||
}
|
||||
else {
|
||||
singleIdLoader = createSingleIdEntityLoader( new LoadQueryInfluencers( factory ) );
|
||||
}
|
||||
// Hibernate Reactive needs to override the loaders
|
||||
singleIdLoader = buildSingleIdEntityLoader();
|
||||
multiIdLoader = buildMultiIdLoader();
|
||||
}
|
||||
|
||||
|
@ -3644,7 +3649,7 @@ public abstract class AbstractEntityPersister
|
|||
final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers();
|
||||
// no subselect fetching for entities for now
|
||||
return isAffectedByInfluencers( influencers )
|
||||
? createSingleIdEntityLoader( influencers )
|
||||
? buildSingleIdEntityLoader( influencers )
|
||||
: getSingleIdLoader();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue