diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java index f2d8d62bd8..d86935c580 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java @@ -16,23 +16,18 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import java.util.List; /** - * Base support for MultiIdEntityLoader implementations + * Base support for {@link MultiIdEntityLoader} implementations. * * @author Steve Ebersole */ -public abstract class AbstractMultiIdEntityLoader implements MultiIdEntityLoader, Preparable { +public abstract class AbstractMultiIdEntityLoader implements MultiIdEntityLoader { private final EntityMappingType entityDescriptor; private final SessionFactoryImplementor sessionFactory; - - private EntityIdentifierMapping identifierMapping; + private final EntityIdentifierMapping identifierMapping; public AbstractMultiIdEntityLoader(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; this.sessionFactory = sessionFactory; - } - - @Override - public void prepare() { identifierMapping = getLoadable().getIdentifierMapping(); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java index 4bbcb1d584..a0321e3a69 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java @@ -32,7 +32,7 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; /** - * SingleIdEntityLoaderSupport implementation based on using a single + * {@link SingleIdEntityLoaderSupport} implementation based on using a single * {@linkplain org.hibernate.type.SqlTypes#ARRAY array} parameter to pass the * entire batch of ids. * @@ -40,14 +40,14 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO */ public class EntityBatchLoaderArrayParam extends SingleIdEntityLoaderSupport - implements EntityBatchLoader, SqlArrayMultiKeyLoader, Preparable { + implements EntityBatchLoader, SqlArrayMultiKeyLoader { private final int domainBatchSize; - private BasicEntityIdentifierMapping identifierMapping; - private JdbcMapping arrayJdbcMapping; - private JdbcParameter jdbcParameter; - private SelectStatement sqlAst; - private JdbcOperationQuerySelect jdbcSelectOperation; + private final BasicEntityIdentifierMapping identifierMapping; + private final JdbcMapping arrayJdbcMapping; + private final JdbcParameter jdbcParameter; + private final SelectStatement sqlAst; + private final JdbcOperationQuerySelect jdbcSelectOperation; /** @@ -75,7 +75,32 @@ public class EntityBatchLoaderArrayParam domainBatchSize ); } - } + + identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); + final Class arrayClass = + Array.newInstance( identifierMapping.getJavaType().getJavaTypeClass(), 0 ).getClass(); + arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( + sessionFactory.getTypeConfiguration().getBasicTypeRegistry().getRegisteredType( arrayClass ), + identifierMapping.getJdbcMapping(), + arrayClass, + sessionFactory + ); + + jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( + getLoadable(), + identifierMapping, + new LoadQueryInfluencers( sessionFactory ), + LockOptions.NONE, + jdbcParameter, + sessionFactory + ); + + jdbcSelectOperation = sessionFactory.getJdbcServices() + .getJdbcEnvironment() + .getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlAst ) + .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); } @Override public int getDomainBatchSize() { @@ -151,35 +176,6 @@ public class EntityBatchLoaderArrayParam return load( pkValue, null, lockOptions, readOnly, session ); } - @Override - public void prepare() { - identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); - final Class arrayClass = - Array.newInstance( identifierMapping.getJavaType().getJavaTypeClass(), 0 ).getClass(); - arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( - sessionFactory.getTypeConfiguration().getBasicTypeRegistry().getRegisteredType( arrayClass ), - identifierMapping.getJdbcMapping(), - arrayClass, - sessionFactory - ); - - jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); - sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( - getLoadable(), - identifierMapping, - new LoadQueryInfluencers( sessionFactory ), - LockOptions.NONE, - jdbcParameter, - sessionFactory - ); - - jdbcSelectOperation = sessionFactory.getJdbcServices() - .getJdbcEnvironment() - .getSqlAstTranslatorFactory() - .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); - } - @Override public String toString() { return String.format( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderInPredicate.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderInPredicate.java index 15b0d193aa..57b89a7455 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderInPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderInPredicate.java @@ -35,10 +35,10 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; /** - * An EntityBatchLoader using one or more SQL queries, which each initialize up to - * {@linkplain #getSqlBatchSize()} entities using a SQL IN predicate restriction - + * An {@link EntityBatchLoader} using one or more SQL queries, which each initialize up + * to {@linkplain #getSqlBatchSize()} entities using a SQL IN predicate restriction - * e.g., {@code ... where id in (?,?,...)}. - *

+ *

* The number of parameters rendered into the SQL is controlled by {@linkplain #getSqlBatchSize()}. * Any unused parameter slots for a particular execution are set to {@code null}. * @@ -46,13 +46,13 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO */ public class EntityBatchLoaderInPredicate extends SingleIdEntityLoaderSupport - implements EntityBatchLoader, SqlInPredicateMultiKeyLoader, Preparable { + implements EntityBatchLoader, SqlInPredicateMultiKeyLoader { private final int domainBatchSize; private final int sqlBatchSize; - private List jdbcParameters; - private SelectStatement sqlAst; - private JdbcOperationQuerySelect jdbcSelectOperation; + private final List jdbcParameters; + private final SelectStatement sqlAst; + private final JdbcOperationQuerySelect jdbcSelectOperation; /** * @param domainBatchSize The maximum number of entities we will initialize for each {@link #load load} @@ -77,6 +77,31 @@ public class EntityBatchLoaderInPredicate sqlBatchSize ); } + + EntityIdentifierMapping identifierMapping = getLoadable().getIdentifierMapping(); + + final int expectedNumberOfParameters = identifierMapping.getJdbcTypeCount() * sqlBatchSize; + + jdbcParameters = arrayList( expectedNumberOfParameters ); + sqlAst = LoaderSelectBuilder.createSelect( + getLoadable(), + // null here means to select everything + null, + identifierMapping, + null, + sqlBatchSize, + new LoadQueryInfluencers( sessionFactory ), + LockOptions.NONE, + jdbcParameters::add, + sessionFactory + ); + assert jdbcParameters.size() == expectedNumberOfParameters; + + jdbcSelectOperation = sessionFactory.getJdbcServices() + .getJdbcEnvironment() + .getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlAst ) + .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); } @Override @@ -300,34 +325,6 @@ public class EntityBatchLoaderInPredicate entityKeys.forEach( batchFetchQueue::removeBatchLoadableEntityKey ); } - @Override - public void prepare() { - EntityIdentifierMapping identifierMapping = getLoadable().getIdentifierMapping(); - - final int expectedNumberOfParameters = identifierMapping.getJdbcTypeCount() * sqlBatchSize; - - jdbcParameters = arrayList( expectedNumberOfParameters ); - sqlAst = LoaderSelectBuilder.createSelect( - getLoadable(), - // null here means to select everything - null, - identifierMapping, - null, - sqlBatchSize, - new LoadQueryInfluencers( sessionFactory ), - LockOptions.NONE, - jdbcParameters::add, - sessionFactory - ); - assert jdbcParameters.size() == expectedNumberOfParameters; - - jdbcSelectOperation = sessionFactory.getJdbcServices() - .getJdbcEnvironment() - .getSqlAstTranslatorFactory() - .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); - } - @Override public String toString() { return String.format( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java index 28af2c4d30..5249286544 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java @@ -48,12 +48,20 @@ import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; /** * @author Steve Ebersole */ -public class MultiIdEntityLoaderArrayParam extends AbstractMultiIdEntityLoader implements SqlArrayMultiKeyLoader, Preparable { - private JdbcMapping arrayJdbcMapping; - private JdbcParameter jdbcParameter; +public class MultiIdEntityLoaderArrayParam extends AbstractMultiIdEntityLoader implements SqlArrayMultiKeyLoader { + private final JdbcMapping arrayJdbcMapping; + private final JdbcParameter jdbcParameter; public MultiIdEntityLoaderArrayParam(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { super( entityDescriptor, sessionFactory ); + final Class arrayClass = createTypedArray( 0 ).getClass(); + arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( + getSessionFactory().getTypeConfiguration().getBasicTypeRegistry().getRegisteredType( arrayClass ), + getIdentifierMapping().getJdbcMapping(), + arrayClass, + getSessionFactory() + ); + jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); } @Override @@ -387,17 +395,4 @@ public class MultiIdEntityLoaderArrayParam extends AbstractMultiIdEntityLoade //noinspection unchecked return (X[]) Array.newInstance( getIdentifierMapping().getJavaType().getJavaTypeClass(), length ); } - - @Override - public void prepare() { - super.prepare(); - final Class arrayClass = createTypedArray( 0 ).getClass(); - arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( - getSessionFactory().getTypeConfiguration().getBasicTypeRegistry().getRegisteredType( arrayClass ), - getIdentifierMapping().getJdbcMapping(), - arrayClass, - getSessionFactory() - ); - jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/Preparable.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/Preparable.java deleted file mode 100644 index f21079dc37..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/Preparable.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.loader.ast.internal; - -/** - * Contract for Loader instances wishing to have a "finish initialization" callback after its Loadable - * has finished initializing. - * - * This allows the owner to create the Loader during its construction and trigger its "prepare" later - * - * @author Steve Ebersole - */ -public interface Preparable { - /** - * Perform the preparation - */ - void prepare(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderStandardImpl.java index 3b95651cd0..a0eacf04c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderStandardImpl.java @@ -24,11 +24,11 @@ import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.ast.tree.expression.JdbcParameter; /** - * Standard implementation of SingleIdEntityLoader + * Standard implementation of {@link org.hibernate.loader.ast.spi.SingleIdEntityLoader}. * * @author Steve Ebersole */ -public class SingleIdEntityLoaderStandardImpl extends SingleIdEntityLoaderSupport implements Preparable { +public class SingleIdEntityLoaderStandardImpl extends SingleIdEntityLoaderSupport { private EnumMap selectByLockMode = new EnumMap<>( LockMode.class ); private EnumMap selectByInternalCascadeProfile; @@ -43,10 +43,6 @@ public class SingleIdEntityLoaderStandardImpl extends SingleIdEntityLoaderSup SessionFactoryImplementor sessionFactory) { // todo (6.0) : consider creating a base AST and "cloning" it super( entityDescriptor, sessionFactory ); - } - - @Override - public void prepare() { // see `org.hibernate.persister.entity.AbstractEntityPersister#createLoaders` // we should pre-load a few - maybe LockMode.NONE and LockMode.READ final LockOptions lockOptions = LockOptions.NONE; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 7cf165d604..9b465c7cb3 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -76,7 +76,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.spi.CachedNaturalIdValueSource; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CollectionKey; @@ -118,20 +117,17 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.LockModeEnumMap; import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.TooManyRowsAffectedException; -import org.hibernate.loader.ast.internal.MultiKeyLoadHelper; import org.hibernate.loader.ast.internal.CacheEntityLoaderHelper; import org.hibernate.engine.profile.internal.FetchProfileAffectee; import org.hibernate.loader.ast.internal.LoaderSelectBuilder; import org.hibernate.loader.ast.internal.LoaderSqlAstCreationState; import org.hibernate.loader.ast.internal.MultiIdEntityLoaderArrayParam; import org.hibernate.loader.ast.internal.MultiIdEntityLoaderStandard; -import org.hibernate.loader.ast.internal.Preparable; import org.hibernate.loader.ast.internal.SingleIdArrayLoadPlan; import org.hibernate.loader.ast.internal.SingleIdEntityLoaderProvidedQueryImpl; import org.hibernate.loader.ast.internal.SingleIdEntityLoaderStandardImpl; import org.hibernate.loader.ast.internal.SingleUniqueKeyEntityLoaderStandard; import org.hibernate.loader.ast.spi.BatchLoaderFactory; -import org.hibernate.loader.ast.spi.Loader; import org.hibernate.loader.ast.spi.MultiIdEntityLoader; import org.hibernate.loader.ast.spi.MultiIdLoadOptions; import org.hibernate.loader.ast.spi.MultiNaturalIdLoader; @@ -3393,31 +3389,13 @@ public abstract class AbstractEntityPersister // 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 ); - prepareLoader( singleIdLoader ); } else { - singleIdLoader = createAndPrepareSingleIdEntityLoader( new LoadQueryInfluencers( factory ) ); + singleIdLoader = createSingleIdEntityLoader( new LoadQueryInfluencers( factory ) ); } - multiIdLoader = buildAndPrepareMultiIdLoader(); + multiIdLoader = buildMultiIdLoader(); } - private MultiIdEntityLoader buildAndPrepareMultiIdLoader() { - MultiIdEntityLoader multiIdLoader = buildMultiIdLoader(); - prepareLoader( multiIdLoader ); - return multiIdLoader; - } - - private SingleIdEntityLoader createAndPrepareSingleIdEntityLoader(LoadQueryInfluencers influencers) { - SingleIdEntityLoader singleIdLoader = createSingleIdEntityLoader( influencers ); - prepareLoader( singleIdLoader ); - return singleIdLoader; - } - - private void prepareLoader(Loader loader) { - if ( loader instanceof Preparable ) { - ( (Preparable) loader ).prepare(); - } - } /** * Load an instance using either the {@code forUpdateLoader} or the outer joining {@code loader}, * depending upon the value of the {@code lock} parameter @@ -3463,7 +3441,7 @@ public abstract class AbstractEntityPersister final LoadQueryInfluencers influencers = session.getLoadQueryInfluencers(); // no subselect fetching for entities for now return isAffectedByInfluencers( influencers ) - ? createAndPrepareSingleIdEntityLoader( influencers ) + ? createSingleIdEntityLoader( influencers ) : getSingleIdLoader(); } }