HHH-12556 Share data structures between similar LoadPlan based EntityLoaders
This commit is contained in:
parent
fcd9467aa3
commit
8916b16d3b
|
@ -28,6 +28,7 @@ import org.hibernate.loader.plan.build.spi.LoadPlanBuildingAssociationVisitation
|
|||
import org.hibernate.loader.plan.build.spi.MetamodelDrivenLoadPlanBuilder;
|
||||
import org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader;
|
||||
import org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory;
|
||||
import org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails;
|
||||
import org.hibernate.loader.plan.exec.query.spi.QueryBuildingParameters;
|
||||
import org.hibernate.loader.plan.exec.spi.LoadQueryDetails;
|
||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||
|
@ -87,6 +88,23 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan
|
|||
);
|
||||
}
|
||||
|
||||
protected AbstractLoadPlanBasedEntityLoader(
|
||||
OuterJoinLoadable entityPersister,
|
||||
SessionFactoryImplementor factory,
|
||||
EntityLoadQueryDetails entityLoaderQueryDetailsTemplate,
|
||||
Type uniqueKeyType,
|
||||
QueryBuildingParameters buildingParameters) {
|
||||
super( factory );
|
||||
this.entityPersister = entityPersister;
|
||||
this.uniqueKeyType = uniqueKeyType;
|
||||
this.entityName = entityPersister.getEntityName();
|
||||
|
||||
this.staticLoadQuery = BatchingLoadQueryDetailsFactory.INSTANCE.makeEntityLoadQueryDetails(
|
||||
entityLoaderQueryDetailsTemplate,
|
||||
buildingParameters
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LoadQueryDetails getStaticLoadQuery() {
|
||||
return staticLoadQuery;
|
||||
|
|
|
@ -12,11 +12,11 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails;
|
||||
import org.hibernate.loader.plan.exec.query.internal.QueryBuildingParametersImpl;
|
||||
import org.hibernate.loader.plan.exec.query.spi.QueryBuildingParameters;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,7 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
|||
|
||||
public static class Builder {
|
||||
private final OuterJoinLoadable persister;
|
||||
private EntityLoader entityLoaderTemplate;
|
||||
private int batchSize = 1;
|
||||
private LoadQueryInfluencers influencers = LoadQueryInfluencers.NONE;
|
||||
private LockMode lockMode = LockMode.NONE;
|
||||
|
@ -53,6 +54,11 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
|||
this.persister = persister;
|
||||
}
|
||||
|
||||
public Builder withEntityLoaderTemplate(EntityLoader entityLoaderTemplate) {
|
||||
this.entityLoaderTemplate = entityLoaderTemplate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withBatchSize(int batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
return this;
|
||||
|
@ -79,6 +85,7 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
|||
|
||||
public EntityLoader byUniqueKey(String[] keyColumnNames, Type keyType) {
|
||||
// capture current values in a new instance of QueryBuildingParametersImpl
|
||||
if ( entityLoaderTemplate == null ) {
|
||||
return new EntityLoader(
|
||||
persister.getFactory(),
|
||||
persister,
|
||||
|
@ -92,6 +99,21 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
|||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new EntityLoader(
|
||||
persister.getFactory(),
|
||||
persister,
|
||||
entityLoaderTemplate,
|
||||
keyType,
|
||||
new QueryBuildingParametersImpl(
|
||||
influencers,
|
||||
batchSize,
|
||||
lockMode,
|
||||
lockOptions
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityLoader(
|
||||
|
@ -121,4 +143,37 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityLoader(
|
||||
SessionFactoryImplementor factory,
|
||||
OuterJoinLoadable persister,
|
||||
EntityLoader entityLoaderTemplate,
|
||||
Type uniqueKeyType,
|
||||
QueryBuildingParameters buildingParameters) throws MappingException {
|
||||
super( persister, factory, entityLoaderTemplate.getStaticLoadQuery(), uniqueKeyType, buildingParameters );
|
||||
if ( log.isDebugEnabled() ) {
|
||||
if ( buildingParameters.getLockOptions() != null ) {
|
||||
log.debugf(
|
||||
"Static select for entity %s [%s:%s]: %s",
|
||||
getEntityName(),
|
||||
buildingParameters.getLockOptions().getLockMode(),
|
||||
buildingParameters.getLockOptions().getTimeOut(),
|
||||
getStaticLoadQuery().getSqlStatement()
|
||||
);
|
||||
}
|
||||
else if ( buildingParameters.getLockMode() != null ) {
|
||||
log.debugf(
|
||||
"Static select for entity %s [%s]: %s",
|
||||
getEntityName(),
|
||||
buildingParameters.getLockMode(),
|
||||
getStaticLoadQuery().getSqlStatement()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityLoadQueryDetails getStaticLoadQuery() {
|
||||
return (EntityLoadQueryDetails) super.getStaticLoadQuery();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.loader.entity.UniqueEntityLoader;
|
|||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
|
||||
/**
|
||||
* LoadPlan-based implementation of the the legacy batch loading strategy
|
||||
* LoadPlan-based implementation of the legacy batch loading strategy
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -57,15 +57,7 @@ public class LegacyBatchingEntityLoaderBuilder extends AbstractBatchingEntityLoa
|
|||
LockMode lockMode,
|
||||
SessionFactoryImplementor factory,
|
||||
LoadQueryInfluencers loadQueryInfluencers) {
|
||||
super( persister );
|
||||
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
|
||||
this.loaders = new EntityLoader[ batchSizes.length ];
|
||||
final EntityLoader.Builder entityLoaderBuilder = EntityLoader.forEntity( persister )
|
||||
.withInfluencers( loadQueryInfluencers )
|
||||
.withLockMode( lockMode );
|
||||
for ( int i = 0; i < batchSizes.length; i++ ) {
|
||||
this.loaders[i] = entityLoaderBuilder.withBatchSize( batchSizes[i] ).byPrimaryKey();
|
||||
}
|
||||
this( persister, maxBatchSize, lockMode, null, factory, loadQueryInfluencers );
|
||||
}
|
||||
|
||||
public LegacyBatchingEntityLoader(
|
||||
|
@ -74,14 +66,29 @@ public class LegacyBatchingEntityLoaderBuilder extends AbstractBatchingEntityLoa
|
|||
LockOptions lockOptions,
|
||||
SessionFactoryImplementor factory,
|
||||
LoadQueryInfluencers loadQueryInfluencers) {
|
||||
this( persister, maxBatchSize, null, lockOptions, factory, loadQueryInfluencers );
|
||||
}
|
||||
|
||||
protected LegacyBatchingEntityLoader(
|
||||
OuterJoinLoadable persister,
|
||||
int maxBatchSize,
|
||||
LockMode lockMode,
|
||||
LockOptions lockOptions,
|
||||
SessionFactoryImplementor factory,
|
||||
LoadQueryInfluencers loadQueryInfluencers) {
|
||||
super( persister );
|
||||
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
|
||||
this.loaders = new EntityLoader[ batchSizes.length ];
|
||||
final EntityLoader.Builder entityLoaderBuilder = EntityLoader.forEntity( persister )
|
||||
.withInfluencers( loadQueryInfluencers )
|
||||
.withLockMode( lockMode )
|
||||
.withLockOptions( lockOptions );
|
||||
for ( int i = 0; i < batchSizes.length; i++ ) {
|
||||
this.loaders[i] = entityLoaderBuilder.withBatchSize( batchSizes[i] ).byPrimaryKey();
|
||||
|
||||
// we create a first entity loader to use it as a template for the others
|
||||
this.loaders[0] = entityLoaderBuilder.withBatchSize( batchSizes[0] ).byPrimaryKey();
|
||||
|
||||
for ( int i = 1; i < batchSizes.length; i++ ) {
|
||||
this.loaders[i] = entityLoaderBuilder.withEntityLoaderTemplate( this.loaders[0] ).withBatchSize( batchSizes[i] ).byPrimaryKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,15 @@ public abstract class AbstractLoadQueryDetails implements LoadQueryDetails {
|
|||
protected final SessionFactoryImplementor getSessionFactory() {
|
||||
return queryProcessor.getSessionFactory();
|
||||
}
|
||||
|
||||
protected LoadPlan getLoadPlan() {
|
||||
return loadPlan;
|
||||
}
|
||||
|
||||
protected String[] getKeyColumnNames() {
|
||||
return keyColumnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point for properly handling the FROM clause and and joins and restrictions
|
||||
*
|
||||
|
|
|
@ -68,6 +68,23 @@ public class BatchingLoadQueryDetailsFactory {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a EntityLoadQueryDetails object based on an existing one and additional elements specific to this one.
|
||||
*
|
||||
* @param entityLoadQueryDetailsTemplate the template
|
||||
* @param buildingParameters And influencers that would affect the generated SQL (mostly we are concerned with those
|
||||
* that add additional joins here)
|
||||
* @return The EntityLoadQueryDetails
|
||||
*/
|
||||
public LoadQueryDetails makeEntityLoadQueryDetails(
|
||||
EntityLoadQueryDetails entityLoadQueryDetailsTemplate,
|
||||
QueryBuildingParameters buildingParameters) {
|
||||
return new EntityLoadQueryDetails(
|
||||
entityLoadQueryDetailsTemplate,
|
||||
buildingParameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BasicCollectionLoadQueryDetails object from the given inputs.
|
||||
*
|
||||
|
|
|
@ -10,8 +10,6 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -20,7 +18,6 @@ import org.hibernate.loader.plan.exec.process.internal.AbstractRowReader;
|
|||
import org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl;
|
||||
import org.hibernate.loader.plan.exec.process.internal.EntityReturnReader;
|
||||
import org.hibernate.loader.plan.exec.process.internal.ResultSetProcessingContextImpl;
|
||||
import org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorHelper;
|
||||
import org.hibernate.loader.plan.exec.process.spi.EntityReferenceInitializer;
|
||||
import org.hibernate.loader.plan.exec.process.spi.ReaderCollector;
|
||||
import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessingContext;
|
||||
|
@ -31,12 +28,9 @@ import org.hibernate.loader.plan.exec.spi.EntityReferenceAliases;
|
|||
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||
import org.hibernate.loader.plan.spi.QuerySpace;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.persister.entity.Queryable;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -90,6 +84,22 @@ public class EntityLoadQueryDetails extends AbstractLoadQueryDetails {
|
|||
generate();
|
||||
}
|
||||
|
||||
protected EntityLoadQueryDetails(
|
||||
EntityLoadQueryDetails initialEntityLoadQueryDetails,
|
||||
QueryBuildingParameters buildingParameters) {
|
||||
super(
|
||||
initialEntityLoadQueryDetails.getLoadPlan(),
|
||||
(AliasResolutionContextImpl) initialEntityLoadQueryDetails.getAliasResolutionContext(),
|
||||
buildingParameters,
|
||||
initialEntityLoadQueryDetails.getKeyColumnNames(),
|
||||
initialEntityLoadQueryDetails.getRootReturn(),
|
||||
initialEntityLoadQueryDetails.getSessionFactory()
|
||||
);
|
||||
this.entityReferenceAliases = initialEntityLoadQueryDetails.entityReferenceAliases;
|
||||
this.readerCollector = initialEntityLoadQueryDetails.readerCollector;
|
||||
generate();
|
||||
}
|
||||
|
||||
private EntityReturn getRootEntityReturn() {
|
||||
return (EntityReturn) getRootReturn();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue