HHH-12556 Share data structures between similar LoadPlan based EntityLoaders
This commit is contained in:
parent
1c1cd47c08
commit
3834c4d149
|
@ -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.build.spi.MetamodelDrivenLoadPlanBuilder;
|
||||||
import org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader;
|
import org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader;
|
||||||
import org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory;
|
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.query.spi.QueryBuildingParameters;
|
||||||
import org.hibernate.loader.plan.exec.spi.LoadQueryDetails;
|
import org.hibernate.loader.plan.exec.spi.LoadQueryDetails;
|
||||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
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
|
@Override
|
||||||
protected LoadQueryDetails getStaticLoadQuery() {
|
protected LoadQueryDetails getStaticLoadQuery() {
|
||||||
return staticLoadQuery;
|
return staticLoadQuery;
|
||||||
|
|
|
@ -12,11 +12,11 @@ import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.CoreLogging;
|
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.internal.QueryBuildingParametersImpl;
|
||||||
import org.hibernate.loader.plan.exec.query.spi.QueryBuildingParameters;
|
import org.hibernate.loader.plan.exec.query.spi.QueryBuildingParameters;
|
||||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +44,7 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final OuterJoinLoadable persister;
|
private final OuterJoinLoadable persister;
|
||||||
|
private EntityLoader entityLoaderTemplate;
|
||||||
private int batchSize = 1;
|
private int batchSize = 1;
|
||||||
private LoadQueryInfluencers influencers = LoadQueryInfluencers.NONE;
|
private LoadQueryInfluencers influencers = LoadQueryInfluencers.NONE;
|
||||||
private LockMode lockMode = LockMode.NONE;
|
private LockMode lockMode = LockMode.NONE;
|
||||||
|
@ -53,6 +54,11 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
||||||
this.persister = persister;
|
this.persister = persister;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder withEntityLoaderTemplate(EntityLoader entityLoaderTemplate) {
|
||||||
|
this.entityLoaderTemplate = entityLoaderTemplate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder withBatchSize(int batchSize) {
|
public Builder withBatchSize(int batchSize) {
|
||||||
this.batchSize = batchSize;
|
this.batchSize = batchSize;
|
||||||
return this;
|
return this;
|
||||||
|
@ -79,18 +85,34 @@ public class EntityLoader extends AbstractLoadPlanBasedEntityLoader {
|
||||||
|
|
||||||
public EntityLoader byUniqueKey(String[] keyColumnNames, Type keyType) {
|
public EntityLoader byUniqueKey(String[] keyColumnNames, Type keyType) {
|
||||||
// capture current values in a new instance of QueryBuildingParametersImpl
|
// capture current values in a new instance of QueryBuildingParametersImpl
|
||||||
return new EntityLoader(
|
if ( entityLoaderTemplate == null ) {
|
||||||
persister.getFactory(),
|
return new EntityLoader(
|
||||||
persister,
|
persister.getFactory(),
|
||||||
keyColumnNames,
|
persister,
|
||||||
keyType,
|
keyColumnNames,
|
||||||
new QueryBuildingParametersImpl(
|
keyType,
|
||||||
influencers,
|
new QueryBuildingParametersImpl(
|
||||||
batchSize,
|
influencers,
|
||||||
lockMode,
|
batchSize,
|
||||||
lockOptions
|
lockMode,
|
||||||
)
|
lockOptions
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new EntityLoader(
|
||||||
|
persister.getFactory(),
|
||||||
|
persister,
|
||||||
|
entityLoaderTemplate,
|
||||||
|
keyType,
|
||||||
|
new QueryBuildingParametersImpl(
|
||||||
|
influencers,
|
||||||
|
batchSize,
|
||||||
|
lockMode,
|
||||||
|
lockOptions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
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
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -57,15 +57,7 @@ public class LegacyBatchingEntityLoaderBuilder extends AbstractBatchingEntityLoa
|
||||||
LockMode lockMode,
|
LockMode lockMode,
|
||||||
SessionFactoryImplementor factory,
|
SessionFactoryImplementor factory,
|
||||||
LoadQueryInfluencers loadQueryInfluencers) {
|
LoadQueryInfluencers loadQueryInfluencers) {
|
||||||
super( persister );
|
this( persister, maxBatchSize, lockMode, null, factory, loadQueryInfluencers );
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LegacyBatchingEntityLoader(
|
public LegacyBatchingEntityLoader(
|
||||||
|
@ -74,14 +66,29 @@ public class LegacyBatchingEntityLoaderBuilder extends AbstractBatchingEntityLoa
|
||||||
LockOptions lockOptions,
|
LockOptions lockOptions,
|
||||||
SessionFactoryImplementor factory,
|
SessionFactoryImplementor factory,
|
||||||
LoadQueryInfluencers loadQueryInfluencers) {
|
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 );
|
super( persister );
|
||||||
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
|
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
|
||||||
this.loaders = new EntityLoader[ batchSizes.length ];
|
this.loaders = new EntityLoader[ batchSizes.length ];
|
||||||
final EntityLoader.Builder entityLoaderBuilder = EntityLoader.forEntity( persister )
|
final EntityLoader.Builder entityLoaderBuilder = EntityLoader.forEntity( persister )
|
||||||
.withInfluencers( loadQueryInfluencers )
|
.withInfluencers( loadQueryInfluencers )
|
||||||
|
.withLockMode( lockMode )
|
||||||
.withLockOptions( lockOptions );
|
.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() {
|
protected final SessionFactoryImplementor getSessionFactory() {
|
||||||
return queryProcessor.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
|
* 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.
|
* Constructs a BasicCollectionLoadQueryDetails object from the given inputs.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,8 +10,6 @@ import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
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.EntityReferenceInitializerImpl;
|
||||||
import org.hibernate.loader.plan.exec.process.internal.EntityReturnReader;
|
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.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.EntityReferenceInitializer;
|
||||||
import org.hibernate.loader.plan.exec.process.spi.ReaderCollector;
|
import org.hibernate.loader.plan.exec.process.spi.ReaderCollector;
|
||||||
import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessingContext;
|
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.EntityReturn;
|
||||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||||
import org.hibernate.loader.plan.spi.QuerySpace;
|
import org.hibernate.loader.plan.spi.QuerySpace;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
|
||||||
import org.hibernate.persister.entity.Joinable;
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||||
import org.hibernate.persister.entity.Queryable;
|
import org.hibernate.persister.entity.Queryable;
|
||||||
import org.hibernate.type.CompositeType;
|
|
||||||
import org.hibernate.type.Type;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -90,6 +84,22 @@ public class EntityLoadQueryDetails extends AbstractLoadQueryDetails {
|
||||||
generate();
|
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() {
|
private EntityReturn getRootEntityReturn() {
|
||||||
return (EntityReturn) getRootReturn();
|
return (EntityReturn) getRootReturn();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue