diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java index 6ad0b85d6d75..31df62ba2dfe 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java @@ -208,7 +208,7 @@ public Join addJoin(JoinTable joinTable, Table table, boolean noDelayInPkColumnC * with correctly typed sub-properties for the metamodel. */ public static void handleGenericComponentProperty(Property property, MemberDetails memberDetails, MetadataBuildingContext context) { - if ( property.getValue() instanceof final Component component ) { + if ( property.getValue() instanceof Component component ) { final var collector = context.getMetadataCollector(); if ( component.isGeneric() && component.getPropertySpan() > 0 && collector.getGenericComponent( component.getComponentClass() ) == null ) { @@ -312,7 +312,7 @@ public void doSecondPass(Map persistentClasses) { final var element = initializedCollection.getElement().copy(); setTypeName( element, memberDetails.getElementType().getName() ); if ( initializedCollection instanceof IndexedCollection indexedCollection ) { - final Value index = indexedCollection.getIndex().copy(); + final var index = indexedCollection.getIndex().copy(); if ( memberDetails.getMapKeyType() != null ) { setTypeName( index, memberDetails.getMapKeyType().getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/log/IncubationLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/log/IncubationLogger.java index ddcff5ae6a81..99e2852fe729 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/log/IncubationLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/log/IncubationLogger.java @@ -19,7 +19,7 @@ * @author Steve Ebersole */ @MessageLogger(projectCode = "HHH") -@ValidIdRange(min = 90006001, max = 90007000) +@ValidIdRange(min = 90006001, max = 90006100) @Internal public interface IncubationLogger { String CATEGORY = SubSystemLogging.BASE + ".incubating"; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java index 3d146b129a4e..e7756a3e585b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java @@ -5,21 +5,15 @@ package org.hibernate.loader.ast.internal; import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.CollectionBatchLoader; -import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; -import org.hibernate.metamodel.mapping.ValuedModelPart; -import org.hibernate.metamodel.mapping.internal.IdClassEmbeddable; import org.hibernate.sql.results.internal.ResultsHelper; -import java.lang.reflect.Array; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.hasSingleId; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.trimIdBatch; @@ -78,63 +72,56 @@ public int getKeyJdbcCount() { abstract void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContractImplementor session); + private CollectionKey collectionKey(Object key) { + return new CollectionKey( getLoadable().getCollectionDescriptor(), key ); + } + @Override public PersistentCollection load(Object key, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Batch fetching collection: " - + collectionInfoString( getLoadable(), key ) ); + MULTI_KEY_LOAD_LOGGER.batchFetchingCollection( + collectionInfoString( getLoadable(), key ) ); } - final Object[] keys = resolveKeysToInitialize( key, session ); - + final var keys = resolveKeysToInitialize( key, session ); if ( hasSingleId( keys ) ) { return singleKeyLoader.load( key, session ); } - initializeKeys( key, keys, session ); - finishInitializingKeys( keys, session ); - final CollectionKey collectionKey = new CollectionKey( getLoadable().getCollectionDescriptor(), key ); - return session.getPersistenceContext().getCollection( collectionKey ); + return session.getPersistenceContext().getCollection( collectionKey( key ) ); } abstract void finishInitializingKeys(Object[] key, SharedSessionContractImplementor session); protected void finishInitializingKey(Object key, SharedSessionContractImplementor session) { - if ( key == null ) { - return; - } - - if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Finishing initializing batch-fetched collection: " - + collectionInfoString( attributeMapping, key ) ); - } + if ( key != null ) { + if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { + MULTI_KEY_LOAD_LOGGER.finishingInitializingBatchFetchedCollection( + collectionInfoString( attributeMapping, key ) ); + } - final PersistenceContext persistenceContext = session.getPersistenceContext(); - final CollectionKey collectionKey = new CollectionKey( getLoadable().getCollectionDescriptor(), key ); - final PersistentCollection collection = persistenceContext.getCollection( collectionKey ); - if ( !collection.wasInitialized() ) { - final CollectionEntry entry = persistenceContext.getCollectionEntry( collection ); - collection.initializeEmptyCollection( entry.getLoadedPersister() ); - ResultsHelper.finalizeCollectionLoading( - persistenceContext, - entry.getLoadedPersister(), - collection, - key, - true - ); + final var persistenceContext = session.getPersistenceContext(); + final var collection = persistenceContext.getCollection( collectionKey( key ) ); + if ( !collection.wasInitialized() ) { + final var entry = persistenceContext.getCollectionEntry( collection ); + collection.initializeEmptyCollection( entry.getLoadedPersister() ); + ResultsHelper.finalizeCollectionLoading( + persistenceContext, + entry.getLoadedPersister(), + collection, + key, + true + ); + } } - } @AllowReflection Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) { final int length = getDomainBatchSize(); - final Object[] keysToInitialize = (Object[]) Array.newInstance( - getKeyType( getLoadable().getKeyDescriptor().getKeyPart() ), - length - ); + final Object[] keysToInitialize = new Object[length]; session.getPersistenceContextInternal().getBatchFetchQueue() .collectBatchLoadableCollectionKeys( length, @@ -145,16 +132,4 @@ Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImp // now trim down the array to the number of keys we found return trimIdBatch( length, keysToInitialize ); } - - protected Class getKeyType(ValuedModelPart keyPart) { - if ( keyPart instanceof NonAggregatedIdentifierMapping nonAggregatedIdentifierMapping ) { - final IdClassEmbeddable idClassEmbeddable = nonAggregatedIdentifierMapping.getIdClassEmbeddable(); - if ( idClassEmbeddable != null ) { - return idClassEmbeddable.getMappedJavaType().getJavaTypeClass(); - } - } - return keyPart.getJavaType().getJavaTypeClass(); - } - - } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractEntityBatchLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractEntityBatchLoader.java index 456042d2998f..2b96683a217d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractEntityBatchLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractEntityBatchLoader.java @@ -7,7 +7,6 @@ import org.hibernate.Hibernate; import org.hibernate.LockMode; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.EntityBatchLoader; @@ -25,7 +24,7 @@ public abstract class AbstractEntityBatchLoader public AbstractEntityBatchLoader(EntityMappingType entityDescriptor, LoadQueryInfluencers influencers) { super( entityDescriptor, influencers.getSessionFactory() ); - this.singleIdLoader = new SingleIdEntityLoaderStandardImpl<>( entityDescriptor, influencers ); + singleIdLoader = new SingleIdEntityLoaderStandardImpl<>( entityDescriptor, influencers ); } protected abstract void initializeEntities( @@ -38,7 +37,7 @@ protected abstract void initializeEntities( protected abstract Object[] resolveIdsToInitialize(Object id, SharedSessionContractImplementor session); - @Override +@Override public final T load( Object id, Object entityInstance, @@ -46,23 +45,21 @@ public final T load( Boolean readOnly, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Batch fetching entity: " - + infoString( getLoadable(), id ) ); + MULTI_KEY_LOAD_LOGGER.batchFetchingEntity( infoString( getLoadable(), id ) ); } - final Object[] ids = resolveIdsToInitialize( id, session ); + final var ids = resolveIdsToInitialize( id, session ); return load( id, ids, hasSingleId( ids ), entityInstance, lockOptions, readOnly, session ); } - @Override +@Override public T load( Object id, Object entityInstance, LockOptions lockOptions, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Batch fetching entity: " - + infoString( getLoadable(), id ) ); + MULTI_KEY_LOAD_LOGGER.batchFetchingEntity( infoString( getLoadable(), id ) ); } final Object[] ids = resolveIdsToInitialize( id, session ); @@ -91,11 +88,11 @@ private T load( if ( hasSingleId || lockOptions.getLockMode() != LockMode.NONE ) { return singleIdLoader.load( id, entityInstance, lockOptions, readOnly, session ); } - - initializeEntities( ids, id, entityInstance, lockOptions, readOnly, session ); - - final EntityKey entityKey = session.generateEntityKey( id, getLoadable().getEntityPersister() ); - //noinspection unchecked - return (T) session.getPersistenceContext().getEntity( entityKey ); + else { + initializeEntities( ids, id, entityInstance, lockOptions, readOnly, session ); + final var entityKey = session.generateEntityKey( id, getLoadable().getEntityPersister() ); + //noinspection unchecked + return (T) session.getPersistenceContext().getEntity( entityKey ); + } } } 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 a5a6344d5d34..08ef24ce5b65 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 @@ -8,20 +8,15 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.EntityKey; -import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.MultiIdEntityLoader; import org.hibernate.loader.ast.spi.MultiIdLoadOptions; -import org.hibernate.loader.internal.CacheLoadHelper.PersistenceContextEntry; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.exec.spi.JdbcSelectExecutor; -import org.hibernate.type.descriptor.java.JavaType; import java.util.ArrayList; import java.util.List; @@ -92,8 +87,7 @@ private List performUnorderedMultiLoad( assert !loadOptions.isOrderReturnEnabled(); assert ids != null; if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Unordered batch load starting: " - + getLoadable().getEntityName() ); + MULTI_KEY_LOAD_LOGGER.unorderedBatchLoadStarting( getLoadable().getEntityName() ); } return unorderedMultiLoad( ids, loadOptions, session ); } @@ -105,8 +99,7 @@ private List performOrderedMultiLoad( assert loadOptions.isOrderReturnEnabled(); assert ids != null; if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Ordered batch load starting: " - + getLoadable().getEntityName() ); + MULTI_KEY_LOAD_LOGGER.orderedMultiLoadStarting( getLoadable().getEntityName() ); } return orderedMultiLoad( ids, loadOptions, session ); } @@ -116,7 +109,7 @@ private List orderedMultiLoad( MultiIdLoadOptions loadOptions, SharedSessionContractImplementor session) { final boolean idCoercionEnabled = isIdCoercionEnabled(); - final JavaType idType = getLoadable().getIdentifierMapping().getJavaType(); + final var idType = getLoadable().getIdentifierMapping().getJavaType(); final int maxBatchSize = maxBatchSize( ids, loadOptions ); @@ -125,23 +118,20 @@ private List orderedMultiLoad( final List idsInBatch = new ArrayList<>(); final List elementPositionsLoadedByBatch = new ArrayList<>(); - final LockOptions lockOptions = lockOptions( loadOptions ); + final var lockOptions = lockOptions( loadOptions ); for ( int i = 0; i < ids.length; i++ ) { final Object id = idCoercionEnabled ? idType.coerce( ids[i], session ) : ids[i]; - final EntityKey entityKey = new EntityKey( id, getLoadable().getEntityPersister() ); - + final var entityKey = new EntityKey( id, getLoadable().getEntityPersister() ); if ( !loadFromEnabledCaches( loadOptions, session, id, lockOptions, entityKey, results, i ) ) { // if we did not hit any of the continues above, // then we need to batch load the entity state. idsInBatch.add( id ); - if ( idsInBatch.size() >= maxBatchSize ) { // we've hit the allotted max-batch-size, perform an "intermediate load" loadEntitiesById( idsInBatch, lockOptions, loadOptions, session ); idsInBatch.clear(); } - // Save the EntityKey instance for use later results.add( i, entityKey ); elementPositionsLoadedByBatch.add( i ); @@ -174,11 +164,11 @@ private void handleResults( SharedSessionContractImplementor session, List elementPositionsLoadedByBatch, List results) { - final PersistenceContext persistenceContext = session.getPersistenceContext(); + final var persistenceContext = session.getPersistenceContext(); for ( Integer position : elementPositionsLoadedByBatch ) { // the element value at this position in the results List should be // the EntityKey for that entity - reuse it - final EntityKey entityKey = (EntityKey) results.get( position ); + final var entityKey = (EntityKey) results.get( position ); session.getPersistenceContextInternal().getBatchFetchQueue().removeBatchLoadableEntityKey( entityKey ); final Object entity = persistenceContext.getEntity( entityKey ); final Object result; @@ -223,8 +213,7 @@ private boolean isLoadFromCaches( if ( loadOptions.isSessionCheckingEnabled() ) { // look for it in the Session first - final PersistenceContextEntry entry = - loadFromSessionCache( entityKey, lockOptions, GET, session ); + final var entry = loadFromSessionCache( entityKey, lockOptions, GET, session ); final Object entity = entry.entity(); if ( entity != null ) { // put a null in the results @@ -254,18 +243,18 @@ protected List unorderedMultiLoad( Object[] ids, MultiIdLoadOptions loadOptions, SharedSessionContractImplementor session) { - final LockOptions lockOptions = lockOptions( loadOptions ); + final var lockOptions = lockOptions( loadOptions ); final List results = arrayList( ids.length ); - final Object[] unresolvableIds = + final var unresolvableIds = resolveInCachesIfEnabled( ids, loadOptions, lockOptions, session, (position, entityKey, resolvedRef) -> results.add( (T) resolvedRef ) ); if ( !isEmpty( unresolvableIds ) ) { loadEntitiesWithUnresolvedIds( unresolvableIds, loadOptions, lockOptions, results, session ); - final BatchFetchQueue batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); - final EntityPersister persister = getLoadable().getEntityPersister(); + final var batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); + final var persister = getLoadable().getEntityPersister(); for ( Object id : unresolvableIds ) { // skip any of the null padded ids - // (actually we could probably even break on the first null) + // (actually, we could probably even break on the first null) if ( id != null ) { // found or not, remove the key from the batch-fetch queue batchFetchQueue.removeBatchLoadableEntityKey( session.generateEntityKey( id, persister ) ); @@ -292,7 +281,7 @@ private Object[] resolveInCachesIfEnabled( // the user requested that we exclude ids corresponding to already managed // entities from the generated load SQL. So here we will iterate all // incoming id values and see whether it corresponds to an existing - // entity associated with the PC. If it does, we add it to the results + // entity associated with the PC. If it does, we add it to the result // list immediately and remove its id from the group of ids to load. // we'll load all of them from the database ? resolveInCaches( ids, loadOptions, lockOptions, session, resolutionConsumer ) @@ -305,18 +294,7 @@ private Object[] resolveInCaches( LockOptions lockOptions, SharedSessionContractImplementor session, ResolutionConsumer resolutionConsumer) { - - final boolean idCoercionEnabled = isIdCoercionEnabled(); - final JavaType idType = getLoadable().getIdentifierMapping().getJavaType(); - - List unresolvedIds = null; - for ( int i = 0; i < ids.length; i++ ) { - final Object id = idCoercionEnabled ? idType.coerce( ids[i], session ) : ids[i]; - final EntityKey entityKey = new EntityKey( id, getLoadable().getEntityPersister() ); - unresolvedIds = - loadFromCaches( loadOptions, lockOptions, resolutionConsumer, id, entityKey, unresolvedIds, i, session ); - } - + final var unresolvedIds = unresolvedIds( ids, loadOptions, lockOptions, session, resolutionConsumer ); if ( isEmpty( unresolvedIds ) ) { // all the given ids were already associated with the Session return null; @@ -331,6 +309,32 @@ else if ( unresolvedIds.size() == ids.length ) { } } + private List unresolvedIds( + Object[] ids, + MultiIdLoadOptions loadOptions, + LockOptions lockOptions, + SharedSessionContractImplementor session, + ResolutionConsumer resolutionConsumer) { + final boolean idCoercionEnabled = isIdCoercionEnabled(); + final var idType = getLoadable().getIdentifierMapping().getJavaType(); + List unresolvedIds = null; + for ( int i = 0; i < ids.length; i++ ) { + final Object id = idCoercionEnabled ? idType.coerce( ids[i], session ) : ids[i]; + unresolvedIds = + loadFromCaches( + loadOptions, + lockOptions, + resolutionConsumer, + id, + new EntityKey( id, getLoadable().getEntityPersister() ), + unresolvedIds, + i, + session + ); + } + return unresolvedIds; + } + // Depending on the implementation, a specific subtype of Object[] (e.g. Integer[]) may be needed. protected abstract Object[] toIdArray(List ids); @@ -352,8 +356,7 @@ private List loadFromCaches( SharedSessionContractImplementor session) { // look for it in the Session first - final PersistenceContextEntry entry = - loadFromSessionCache( entityKey, lockOptions, GET, session ); + final var entry = loadFromSessionCache( entityKey, lockOptions, GET, session ); final Object sessionEntity; if ( loadOptions.isSessionCheckingEnabled() ) { sessionEntity = entry.entity(); @@ -387,7 +390,7 @@ private List loadFromCaches( } private Object loadFromSecondLevelCache(EntityKey entityKey, LockOptions lockOptions, SharedSessionContractImplementor session) { - final EntityPersister persister = getLoadable().getEntityPersister(); + final var persister = getLoadable().getEntityPersister(); return session.loadFromSecondLevelCache( persister, entityKey, null, lockOptions.getLockMode() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiNaturalIdLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiNaturalIdLoader.java index d6355bd3b293..722752976f8a 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiNaturalIdLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiNaturalIdLoader.java @@ -6,14 +6,12 @@ import org.hibernate.LockOptions; -import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions; import org.hibernate.loader.ast.spi.MultiNaturalIdLoader; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.NaturalIdMapping; import java.util.List; import java.util.function.Consumer; @@ -52,14 +50,13 @@ private List performUnorderedMultiLoad( MultiNaturalIdLoadOptions loadOptions, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Unordered batch load starting: " - + getEntityDescriptor().getEntityName() ); + MULTI_KEY_LOAD_LOGGER.unorderedBatchLoadStarting( getEntityDescriptor().getEntityName() ); } return unorderedMultiLoad( naturalIds, loadOptions, session ); } private static LockOptions lockOptions(MultiNaturalIdLoadOptions loadOptions) { - final LockOptions lockOptions = loadOptions.getLockOptions(); + final var lockOptions = loadOptions.getLockOptions(); return lockOptions == null ? new LockOptions() : lockOptions; } @@ -68,8 +65,8 @@ private List unorderedMultiLoad( MultiNaturalIdLoadOptions loadOptions, SharedSessionContractImplementor session) { final List results = arrayList( naturalIds.length ); - final LockOptions lockOptions = lockOptions( loadOptions ); - final Object[] unresolvedIds = + final var lockOptions = lockOptions( loadOptions ); + final var unresolvedIds = checkPersistenceContextForCachedResults( naturalIds, loadOptions, session, lockOptions, results::add ); if ( !isEmpty( unresolvedIds ) ) { results.addAll( loadEntitiesWithUnresolvedIds( unresolvedIds, loadOptions, lockOptions, session ) ); @@ -88,8 +85,7 @@ private List performOrderedMultiLoad( MultiNaturalIdLoadOptions options, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Ordered MultiLoad starting: " - + getEntityDescriptor().getEntityName() ); + MULTI_KEY_LOAD_LOGGER.orderedMultiLoadStarting( getEntityDescriptor().getEntityName() ); } return orderedMultiLoad( naturalIds, options, session ); } @@ -98,8 +94,8 @@ private List orderedMultiLoad( K[] naturalIds, MultiNaturalIdLoadOptions loadOptions, SharedSessionContractImplementor session) { - final LockOptions lockOptions = lockOptions( loadOptions ); - final Object[] unresolvedIds = + final var lockOptions = lockOptions( loadOptions ); + final var unresolvedIds = checkPersistenceContextForCachedResults( naturalIds, loadOptions, session, lockOptions, result -> {} ); if ( !isEmpty( unresolvedIds ) ) { loadEntitiesWithUnresolvedIds( unresolvedIds, loadOptions, lockOptions, session ); @@ -111,7 +107,7 @@ private List sortResults( K[] naturalIds, MultiNaturalIdLoadOptions loadOptions, SharedSessionContractImplementor session) { - final PersistenceContext context = session.getPersistenceContextInternal(); + final var context = session.getPersistenceContextInternal(); final List results = arrayList( naturalIds.length ); for ( K naturalId : naturalIds ) { final Object entity = entityForNaturalId( context, naturalId ); @@ -131,7 +127,7 @@ private List sortResults( } private Object entityForNaturalId(PersistenceContext context, K naturalId) { - final EntityMappingType descriptor = getEntityDescriptor(); + final var descriptor = getEntityDescriptor(); final Object id = context.getNaturalIdResolutions().findCachedIdByNaturalId( naturalId, descriptor ); // id can be null if a non-existent natural id is requested, or a mutable natural id was changed and then deleted return id == null ? null : context.getEntity( new EntityKey( id, descriptor.getEntityPersister() ) ); @@ -144,13 +140,13 @@ private Object[] checkPersistenceContextForCachedResults( LockOptions lockOptions, Consumer results ) { final List unresolvedIds = arrayList( naturalIds.length ); - final PersistenceContext context = session.getPersistenceContextInternal(); - final NaturalIdMapping naturalIdMapping = getEntityDescriptor().getNaturalIdMapping(); + final var context = session.getPersistenceContextInternal(); + final var naturalIdMapping = getEntityDescriptor().getNaturalIdMapping(); for ( K naturalId : naturalIds ) { final Object entity = entityForNaturalId( context, naturalIdMapping.normalizeInput( naturalId ) ); if ( entity != null ) { // Entity is already in the persistence context - final EntityEntry entry = context.getEntry( entity ); + final var entry = context.getEntry( entity ); if ( loadOptions.isReturnOfDeletedEntitiesEnabled() || !entry.getStatus().isDeletedOrGone() ) { // either a managed entry, or a deleted one with returnDeleted enabled @@ -161,8 +157,8 @@ private Object[] checkPersistenceContextForCachedResults( } else { // entity either doesn't exist or hasn't been loaded in the PC yet, in both cases we add - // the natural id to the ids that still need to be recovered, in case the id corresponds - // to a nonexistent instance nothing will be in the results for it, which is ok in + // the natural id to the ids that still need to be recovered; in case the id corresponds + // to a nonexistent instance, nothing will be in the results for it, which is OK in an // unordered multiload unresolvedIds.add( naturalId ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractNaturalIdLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractNaturalIdLoader.java index a09b031ac868..b8e5529868fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractNaturalIdLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractNaturalIdLoader.java @@ -4,12 +4,6 @@ */ package org.hibernate.loader.ast.internal; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - import org.hibernate.HibernateException; import org.hibernate.LockOptions; import org.hibernate.engine.spi.LoadQueryInfluencers; @@ -31,7 +25,6 @@ import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; import org.hibernate.sql.ast.tree.predicate.Predicate; @@ -39,19 +32,23 @@ import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.BaseExecutionContext; import org.hibernate.sql.exec.internal.CallbackImpl; +import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.spi.Callback; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.exec.spi.JdbcParameterBinding; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; -import org.hibernate.sql.results.graph.*; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.RowTransformerSingularReturnImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; -import org.hibernate.stat.spi.StatisticsImplementor; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -90,13 +87,14 @@ public EntityMappingType getLoadable() { @Override public T load(Object naturalIdValue, NaturalIdLoadOptions options, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); + final var factory = session.getFactory(); - final LockOptions lockOptions = options.getLockOptions() == null - ? new LockOptions() - : options.getLockOptions(); + final var lockOptions = + options.getLockOptions() == null + ? new LockOptions() + : options.getLockOptions(); - final SelectStatement sqlSelect = LoaderSelectBuilder.createSelect( + final var sqlSelect = LoaderSelectBuilder.createSelect( getLoadable(), null, // null here means to select everything true, @@ -109,7 +107,7 @@ public T load(Object naturalIdValue, NaturalIdLoadOptions options, SharedSession factory ); - final QuerySpec querySpec = sqlSelect.getQuerySpec(); + final var querySpec = sqlSelect.getQuerySpec(); return executeNaturalIdQuery( naturalIdValue, lockOptions, @@ -150,7 +148,7 @@ protected Expression resolveColumnReference( TableGroup rootTableGroup, SelectableMapping selectableMapping, SqlExpressionResolver sqlExpressionResolver) { - final TableReference tableReference = + final var tableReference = rootTableGroup.getTableReference( rootTableGroup.getNavigablePath(), selectableMapping.getContainingTableExpression() ); if ( tableReference == null ) { @@ -177,22 +175,23 @@ public Object resolveNaturalIdToId(Object naturalIdValue, SharedSessionContractI ); } - final SessionFactoryImplementor factory = session.getFactory(); - final NavigablePath entityPath = new NavigablePath( entityDescriptor.getRootPathName() ); - final QuerySpec rootQuerySpec = new QuerySpec( true ); + final var factory = session.getFactory(); + final var entityPath = new NavigablePath( entityDescriptor.getRootPathName() ); + final var rootQuerySpec = new QuerySpec( true ); - final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState( - rootQuerySpec, - new SqlAliasBaseManager(), - new SimpleFromClauseAccessImpl(), - LockOptions.NONE, - (fetchParent, creationState) -> ImmutableFetchList.EMPTY, - true, - new LoadQueryInfluencers( factory ), - factory.getSqlTranslationEngine() - ); + final var sqlAstCreationState = + new LoaderSqlAstCreationState( + rootQuerySpec, + new SqlAliasBaseManager(), + new SimpleFromClauseAccessImpl(), + LockOptions.NONE, + (fetchParent, creationState) -> ImmutableFetchList.EMPTY, + true, + new LoadQueryInfluencers( factory ), + factory.getSqlTranslationEngine() + ); - final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup( + final var rootTableGroup = entityDescriptor.createRootTableGroup( true, entityPath, null, @@ -204,7 +203,7 @@ public Object resolveNaturalIdToId(Object naturalIdValue, SharedSessionContractI rootQuerySpec.getFromClause().addRoot( rootTableGroup ); sqlAstCreationState.getFromClauseAccess().registerTableGroup( entityPath, rootTableGroup ); - final DomainResult domainResult = + final var domainResult = entityDescriptor.getIdentifierMapping().createDomainResult( rootTableGroup.getNavigablePath() .append( EntityIdentifierMapping.ID_ROLE_NAME ), @@ -232,9 +231,9 @@ protected R executeNaturalIdQuery( Consumer predicateConsumer, LoaderSqlAstCreationState sqlAstCreationState, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); + final var factory = session.getFactory(); - final JdbcParameterBindings bindings = + final var bindings = new JdbcParameterBindingsImpl( naturalIdMapping.getJdbcTypeCount() ); applyNaturalIdRestriction( naturalIdMapping().normalizeInput( naturalIdValue ), @@ -245,10 +244,10 @@ protected R executeNaturalIdQuery( session ); - final QueryOptions queryOptions = new SimpleQueryOptions( lockOptions, false ); + final var queryOptions = new SimpleQueryOptions( lockOptions, false ); final var jdbcSelect = createJdbcOperationQuerySelect( sqlSelect, factory, bindings, queryOptions ); - final StatisticsImplementor statistics = factory.getStatistics(); + final var statistics = factory.getStatistics(); final boolean statisticsEnabled = statistics.isStatisticsEnabled(); final long startTime = statisticsEnabled ? System.nanoTime() : -1L; @@ -296,11 +295,11 @@ private static JdbcOperationQuerySelect createJdbcOperationQuerySelect( @Override public Object resolveIdToNaturalId(Object id, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); - final EntityIdentifierMapping identifierMapping = entityDescriptor().getIdentifierMapping(); + final var factory = session.getFactory(); + final var identifierMapping = entityDescriptor().getIdentifierMapping(); - final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder(); - final SelectStatement sqlSelect = LoaderSelectBuilder.createSelect( + final var builder = JdbcParametersList.newBuilder(); + final var sqlSelect = LoaderSelectBuilder.createSelect( entityDescriptor(), singletonList( naturalIdMapping() ), identifierMapping, @@ -311,8 +310,8 @@ public Object resolveIdToNaturalId(Object id, SharedSessionContractImplementor s builder::add, factory ); - final JdbcParametersList jdbcParameters = builder.build(); - final JdbcParameterBindings bindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); + final var jdbcParameters = builder.build(); + final var bindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); final int offset = bindings.registerParametersForEachJdbcValue( id, identifierMapping, jdbcParameters, session ); assert offset == jdbcParameters.size(); @@ -350,14 +349,14 @@ void applyRestriction( Object jdbcValue, SelectableMapping jdbcValueMapping, SqlExpressionResolver expressionResolver) { - final Expression columnReference = + final var columnReference = resolveColumnReference( rootTableGroup, jdbcValueMapping, expressionResolver ); if ( jdbcValue == null ) { predicateConsumer.accept( new NullnessPredicate( columnReference ) ); } else { - final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcValueMapping.getJdbcMapping() ); - final ComparisonPredicate predicate = + final var jdbcParameter = new JdbcParameterImpl( jdbcValueMapping.getJdbcMapping() ); + final var predicate = new ComparisonPredicate( columnReference, ComparisonOperator.EQUAL, jdbcParameter ); predicateConsumer.accept( predicate ); jdbcParameterConsumer.accept( jdbcParameter, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java index 63a252fcaeaa..66280edf96f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java @@ -20,8 +20,6 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.query.spi.QueryOptions; import org.hibernate.sql.ast.tree.expression.JdbcParameter; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; @@ -32,7 +30,6 @@ import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; -import static java.lang.reflect.Array.newInstance; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.hasSingleId; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.trimIdBatch; import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; @@ -46,7 +43,7 @@ public class CollectionBatchLoaderArrayParam extends AbstractCollectionBatchLoader implements SqlArrayMultiKeyLoader { - private final Class keyDomainType; + private final JdbcMapping arrayJdbcMapping; private final JdbcParameter jdbcParameter; private final SelectStatement sqlSelect; @@ -60,17 +57,15 @@ public CollectionBatchLoaderArrayParam( super( domainBatchSize, loadQueryInfluencers, attributeMapping, sessionFactory ); if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Batch fetching enabled for collection '%s' using ARRAY strategy with batch size %s", + MULTI_KEY_LOAD_LOGGER.enabledCollectionArray( attributeMapping.getNavigableRole().getFullPath(), domainBatchSize ); } - final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor(); - final JdbcMapping jdbcMapping = keyDescriptor.getSingleJdbcMapping(); - final Class jdbcJavaTypeClass = jdbcMapping.getJdbcJavaType().getJavaTypeClass(); - keyDomainType = getKeyType( keyDescriptor.getKeyPart() ); + final var keyDescriptor = getLoadable().getKeyDescriptor(); + final var jdbcMapping = keyDescriptor.getSingleJdbcMapping(); + final var jdbcJavaTypeClass = jdbcMapping.getJdbcJavaType().getJavaTypeClass(); arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( jdbcMapping, @@ -88,8 +83,8 @@ public CollectionBatchLoaderArrayParam( getSessionFactory() ); - final QuerySpec querySpec = sqlSelect.getQueryPart().getFirstQuerySpec(); - final TableGroup tableGroup = querySpec.getFromClause().getRoots().get( 0 ); + final var querySpec = sqlSelect.getQueryPart().getFirstQuerySpec(); + final var tableGroup = querySpec.getFromClause().getRoots().get( 0 ); attributeMapping.applySoftDeleteRestrictions( tableGroup, querySpec::applyPredicate ); jdbcSelectOperation = getSessionFactory().getJdbcServices() @@ -100,7 +95,7 @@ public CollectionBatchLoaderArrayParam( } @Override public PersistentCollection load(Object keyBeingLoaded, SharedSessionContractImplementor session) { - final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor(); + final var keyDescriptor = getLoadable().getKeyDescriptor(); if ( keyDescriptor.isEmbedded() ) { assert keyDescriptor.getJdbcTypeCount() == 1; return loadEmbeddable( keyBeingLoaded, session, keyDescriptor ); @@ -108,7 +103,6 @@ public PersistentCollection load(Object keyBeingLoaded, SharedSessionContract else { return super.load( keyBeingLoaded, session ); } - } @AllowReflection @@ -117,34 +111,31 @@ private PersistentCollection loadEmbeddable( SharedSessionContractImplementor session, ForeignKeyDescriptor keyDescriptor) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.trace( "Batch fetching collection: " - + collectionInfoString( getLoadable(), keyBeingLoaded ) ); + MULTI_KEY_LOAD_LOGGER.batchFetchingCollection( + collectionInfoString( getLoadable(), keyBeingLoaded ) ); } final int length = getDomainBatchSize(); - final Object[] keysToInitialize = (Object[]) newInstance( - jdbcParameter.getExpressionType() - .getSingleJdbcMapping() - .getJdbcJavaType() - .getJavaTypeClass() - .getComponentType(), - length - ); - final Object[] embeddedKeys = (Object[]) newInstance( keyDomainType, length ); + final Object[] keysToInitialize = new Object[length]; + final Object[] embeddedKeys = new Object[length]; session.getPersistenceContextInternal().getBatchFetchQueue() .collectBatchLoadableCollectionKeys( length, (index, key) -> - keyDescriptor.forEachJdbcValue( key, (i, value, jdbcMapping) -> { - keysToInitialize[index] = value; - embeddedKeys[index] = key; - }, session ) + keyDescriptor.forEachJdbcValue( + key, + (i, value, jdbcMapping) -> { + keysToInitialize[index] = value; + embeddedKeys[index] = key; + }, + session + ) , keyBeingLoaded, getLoadable() ); // now trim down the array to the number of keys we found - final Object[] keys = trimIdBatch( length, keysToInitialize ); + final var keys = trimIdBatch( length, keysToInitialize ); if ( hasSingleId( keys ) ) { return singleKeyLoader.load( keyBeingLoaded, session ); @@ -157,43 +148,41 @@ private PersistentCollection loadEmbeddable( finishInitializingKey( initializedKey, session ); } } - final CollectionKey collectionKey = new CollectionKey( - getLoadable().getCollectionDescriptor(), - keyBeingLoaded - ); - return session.getPersistenceContext().getCollection( collectionKey ); + return session.getPersistenceContext() + .getCollection( collectionKey( keyBeingLoaded ) ); + } + + private CollectionKey collectionKey(Object keyBeingLoaded) { + return new CollectionKey( getLoadable().getCollectionDescriptor(), keyBeingLoaded ); } @Override void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Collection keys to initialize via batch fetching (%s) %s", - collectionInfoString( getLoadable(), key ), - keysToInitialize ); + MULTI_KEY_LOAD_LOGGER.collectionKeysToInitialize( + collectionInfoString( getLoadable(), key ), keysToInitialize ); } assert jdbcSelectOperation != null; assert jdbcParameter != null; - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(1); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl(1); jdbcParameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( arrayJdbcMapping, keysToInitialize ) ); - final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( - session.getPersistenceContext().getBatchFetchQueue(), - sqlSelect, - JdbcParametersList.singleton( jdbcParameter ), - jdbcParameterBindings - ); - session.getJdbcServices().getJdbcSelectExecutor().list( jdbcSelectOperation, jdbcParameterBindings, new ExecutionContextWithSubselectFetchHandler( session, - subSelectFetchableKeysHandler + SubselectFetch.createRegistrationHandler( + session.getPersistenceContext().getBatchFetchQueue(), + sqlSelect, + JdbcParametersList.singleton( jdbcParameter ), + jdbcParameterBindings + ) ), RowTransformerStandardImpl.instance(), ListResultsConsumer.UniqueSemantic.FILTER @@ -210,18 +199,22 @@ void finishInitializingKeys(Object[] keys, SharedSessionContractImplementor sess @Override @AllowReflection Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) { - final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor(); + final var keyDescriptor = getLoadable().getKeyDescriptor(); if( keyDescriptor.isEmbedded()){ assert keyDescriptor.getJdbcTypeCount() == 1; final int length = getDomainBatchSize(); - final Object[] keysToInitialize = (Object[]) newInstance( keyDescriptor.getSingleJdbcMapping().getJdbcJavaType().getJavaTypeClass(), length ); + final var keysToInitialize = new Object[length]; session.getPersistenceContextInternal().getBatchFetchQueue() .collectBatchLoadableCollectionKeys( length, (index, key) -> - keyDescriptor.forEachJdbcValue( key, (i, value, jdbcMapping) -> { - keysToInitialize[index] = value; - }, session ) + keyDescriptor.forEachJdbcValue( + key, + (i, value, jdbcMapping) -> { + keysToInitialize[index] = value; + }, + session + ) , keyBeingLoaded, getLoadable() diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderInPredicate.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderInPredicate.java index 5c6afcd112d2..efea2c40a173 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderInPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderInPredicate.java @@ -5,7 +5,6 @@ package org.hibernate.loader.ast.internal; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -14,16 +13,14 @@ import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.query.spi.QueryOptions; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.countIds; import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; import static org.hibernate.pretty.MessageHelper.collectionInfoString; +import static org.hibernate.sql.exec.spi.JdbcParameterBindings.NO_BINDINGS; /** * {@link CollectionBatchLoader} for batch fetching using a SQL {@code IN} predicate. @@ -47,20 +44,19 @@ public CollectionBatchLoaderInPredicate( super( domainBatchSize, influencers, attributeMapping, sessionFactory ); keyColumnCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount(); - sqlBatchSize = sessionFactory.getJdbcServices() - .getDialect() - .getBatchLoadSizingStrategy() - .determineOptimalBatchLoadSize( keyColumnCount, domainBatchSize, false ); + sqlBatchSize = + sessionFactory.getJdbcServices().getDialect() + .getBatchLoadSizingStrategy() + .determineOptimalBatchLoadSize( keyColumnCount, domainBatchSize, false ); if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Batch fetching enabled for collection '%s' using IN-predicate with batch size %s (%s)", + MULTI_KEY_LOAD_LOGGER.enabledCollectionInPredicate( attributeMapping.getNavigableRole().getFullPath(), sqlBatchSize, domainBatchSize ); } - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(); + final var jdbcParametersBuilder = JdbcParametersList.newBuilder(); this.sqlAst = LoaderSelectBuilder.createSelect( attributeMapping, null, @@ -73,32 +69,30 @@ public CollectionBatchLoaderInPredicate( sessionFactory ); - final QuerySpec querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); - final TableGroup tableGroup = querySpec.getFromClause().getRoots().get( 0 ); + final var querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); + final var tableGroup = querySpec.getFromClause().getRoots().get( 0 ); attributeMapping.applySoftDeleteRestrictions( tableGroup, querySpec::applyPredicate ); - this.jdbcParameters = jdbcParametersBuilder.build(); - assert this.jdbcParameters.size() == this.sqlBatchSize * this.keyColumnCount; + jdbcParameters = jdbcParametersBuilder.build(); + assert jdbcParameters.size() == sqlBatchSize * keyColumnCount; - jdbcSelect = sessionFactory.getJdbcServices() - .getJdbcEnvironment() - .getSqlAstTranslatorFactory() - .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); + jdbcSelect = + sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlAst ) + .translate( NO_BINDINGS, QueryOptions.NONE ); } @Override void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContractImplementor session) { final boolean loggerDebugEnabled = MULTI_KEY_LOAD_LOGGER.isDebugEnabled(); if ( loggerDebugEnabled ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Collection keys to initialize via batch fetching (%s) %s", + MULTI_KEY_LOAD_LOGGER.collectionKeysToInitialize( collectionInfoString( getLoadable(), key ), keysToInitialize ); } - final MultiKeyLoadChunker chunker = new MultiKeyLoadChunker<>( + final var chunker = new MultiKeyLoadChunker<>( sqlBatchSize, keyColumnCount, getLoadable().getKeyDescriptor(), @@ -107,27 +101,28 @@ void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContract jdbcSelect ); - final BatchFetchQueue batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); + final var batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); chunker.processChunks( keysToInitialize, countIds( keysToInitialize ), - (jdbcParameterBindings, session1) -> { - // Create a RegistrationHandler for handling any subselect fetches we encounter handling this chunk - final SubselectFetch.RegistrationHandler registrationHandler = SubselectFetch.createRegistrationHandler( - batchFetchQueue, - sqlAst, - jdbcParameters, - jdbcParameterBindings - ); - return new ExecutionContextWithSubselectFetchHandler( session, registrationHandler ); - }, + (jdbcParameterBindings, session1) -> + // Create a RegistrationHandler for handling any + // subselect fetches we encounter handling this chunk + new ExecutionContextWithSubselectFetchHandler( + session, + SubselectFetch.createRegistrationHandler( + batchFetchQueue, + sqlAst, + jdbcParameters, + jdbcParameterBindings + ) + ), (key1, relativePosition, absolutePosition) -> { }, (startIndex) -> { if ( loggerDebugEnabled ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Processing collection batch-fetch chunk (%s) %s - %s", + MULTI_KEY_LOAD_LOGGER.processingCollectionBatchFetchChunk( collectionInfoString( getLoadable(), key ), startIndex, startIndex + (sqlBatchSize-1) @@ -136,8 +131,7 @@ void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContract }, (startIndex, nonNullElementCount) -> { if ( loggerDebugEnabled ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Finishing collection batch-fetch chunk (%s) %s - %s (%s)", + MULTI_KEY_LOAD_LOGGER.finishingCollectionBatchFetchChunk( collectionInfoString( getLoadable(), key ), startIndex, startIndex + (sqlBatchSize-1), diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionElementLoaderByIndex.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionElementLoaderByIndex.java index 3e218ee7c8c9..b37cfe985b56 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionElementLoaderByIndex.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionElementLoaderByIndex.java @@ -8,25 +8,17 @@ import java.util.List; import org.hibernate.LockOptions; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.Loader; -import org.hibernate.metamodel.mapping.CollectionPart; -import org.hibernate.metamodel.mapping.EntityIdentifierMapping; -import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.query.spi.QueryOptions; -import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.BaseExecutionContext; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; @@ -64,30 +56,29 @@ public CollectionElementLoaderByIndex( this.attributeMapping = attributeMapping; this.baseIndex = baseIndex; - final ForeignKeyDescriptor keyDescriptor = attributeMapping.getKeyDescriptor(); - final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor(); + final var keyDescriptor = attributeMapping.getKeyDescriptor(); + final var indexDescriptor = attributeMapping.getIndexDescriptor(); - List restrictedParts = new ArrayList<>(); + final List restrictedParts = new ArrayList<>(); restrictedParts.add( keyDescriptor ); if ( indexDescriptor instanceof EntityCollectionPart entityCollectionPart ) { - EntityIdentifierMapping identifierMapping = entityCollectionPart.getEntityMappingType() - .getIdentifierMapping(); + var identifierMapping = + entityCollectionPart.getEntityMappingType() + .getIdentifierMapping(); restrictedParts.add( identifierMapping ); - this.keyJdbcCount = keyDescriptor.getJdbcTypeCount() + - identifierMapping.getJdbcTypeCount(); + keyJdbcCount = keyDescriptor.getJdbcTypeCount() + identifierMapping.getJdbcTypeCount(); } else { restrictedParts.add( indexDescriptor ); - this.keyJdbcCount = keyDescriptor.getJdbcTypeCount() + - indexDescriptor.getJdbcTypeCount(); + keyJdbcCount = keyDescriptor.getJdbcTypeCount() + indexDescriptor.getJdbcTypeCount(); } - List partsToSelect = new ArrayList<>(); + final List partsToSelect = new ArrayList<>(); partsToSelect.add( attributeMapping.getElementDescriptor() ); - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder( keyJdbcCount ); - this.sqlAst = LoaderSelectBuilder.createSelect( + final var jdbcParametersBuilder = JdbcParametersList.newBuilder( keyJdbcCount ); + sqlAst = LoaderSelectBuilder.createSelect( attributeMapping, partsToSelect, restrictedParts, @@ -98,7 +89,7 @@ public CollectionElementLoaderByIndex( jdbcParametersBuilder::add, sessionFactory ); - this.jdbcParameters = jdbcParametersBuilder.build(); + jdbcParameters = jdbcParametersBuilder.build(); } @Override @@ -119,12 +110,8 @@ public JdbcParametersList getJdbcParameters() { } public Object load(Object key, Object index, SharedSessionContractImplementor session) { - final SessionFactoryImplementor sessionFactory = session.getFactory(); - final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); - final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); - final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount ); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount ); int offset = jdbcParameterBindings.registerParametersForEachJdbcValue( key, @@ -140,10 +127,14 @@ public Object load(Object key, Object index, SharedSessionContractImplementor se session ); assert offset == jdbcParameters.size(); - final JdbcOperationQuerySelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst ) - .translate( jdbcParameterBindings, QueryOptions.NONE ); - List list = jdbcServices.getJdbcSelectExecutor().list( + final var sessionFactory = session.getFactory(); + final var jdbcServices = sessionFactory.getJdbcServices(); + final var jdbcSelect = + jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlAst ) + .translate( jdbcParameterBindings, QueryOptions.NONE ); + var list = jdbcServices.getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, new BaseExecutionContext( session ), @@ -152,11 +143,7 @@ public Object load(Object key, Object index, SharedSessionContractImplementor se ListResultsConsumer.UniqueSemantic.FILTER, 1 ); - - if ( list.isEmpty() ) { - return null; - } - return list.get( 0 ); + return list.isEmpty() ? null : list.get( 0 ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderNamedQuery.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderNamedQuery.java index 682ece681d7d..26651e8fd8ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderNamedQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderNamedQuery.java @@ -13,7 +13,6 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.QueryTypeMismatchException; import org.hibernate.query.named.NamedQueryMemento; -import org.hibernate.query.spi.QueryImplementor; import jakarta.persistence.Parameter; @@ -38,7 +37,7 @@ public PluralAttributeMapping getLoadable() { @Override public PersistentCollection load(Object key, SharedSessionContractImplementor session) { - final QueryImplementor query = namedQueryMemento.toQuery( session ); + final var query = namedQueryMemento.toQuery( session ); //noinspection unchecked query.setParameter( (Parameter) query.getParameters().iterator().next(), key ); query.setHibernateFlushMode( FlushMode.MANUAL ); @@ -49,11 +48,10 @@ public PersistentCollection load(Object key, SharedSessionContractImplementor return persistentCollection; } else { - // using annotations we have no way to specify a @CollectionResult - final CollectionKey collectionKey = new CollectionKey( persister, key ); - final PersistentCollection collection = + // using annotations, we have no way to specify a @CollectionResult + final var collection = session.getPersistenceContextInternal() - .getCollection( collectionKey ); + .getCollection( new CollectionKey( persister, key ) ); for ( Object element : resultList ) { if ( element != null && !persister.getElementType().getReturnedClass().isInstance( element ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSingleKey.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSingleKey.java index 0bcbbc546313..4ff1caf44f74 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSingleKey.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSingleKey.java @@ -6,7 +6,6 @@ import org.hibernate.LockOptions; import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.EntityHolder; import org.hibernate.engine.spi.LoadQueryInfluencers; @@ -16,18 +15,16 @@ import org.hibernate.loader.ast.spi.CollectionLoader; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.query.spi.QueryOptions; -import org.hibernate.sql.ast.tree.from.FromClause; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.BaseExecutionContext; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; +import static org.hibernate.sql.exec.spi.JdbcParameterBindings.NO_BINDINGS; + /** * Main implementation of CollectionLoader for handling a load of a single collection-key * @@ -48,10 +45,10 @@ public CollectionLoaderSingleKey( SessionFactoryImplementor sessionFactory) { this.attributeMapping = attributeMapping; - this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount(); - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(); + keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount(); + final var jdbcParametersBuilder = JdbcParametersList.newBuilder(); - this.sqlAst = LoaderSelectBuilder.createSelect( + sqlAst = LoaderSelectBuilder.createSelect( attributeMapping, null, attributeMapping.getKeyDescriptor(), @@ -63,17 +60,15 @@ public CollectionLoaderSingleKey( sessionFactory ); - final QuerySpec querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); - final FromClause fromClause = querySpec.getFromClause(); - final TableGroup tableGroup = fromClause.getRoots().get( 0 ); + final var querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); + final var tableGroup = querySpec.getFromClause().getRoots().get( 0 ); attributeMapping.applySoftDeleteRestrictions( tableGroup, querySpec::applyPredicate ); - this.jdbcParameters = jdbcParametersBuilder.build(); - this.jdbcSelect = sessionFactory.getJdbcServices() - .getJdbcEnvironment() - .getSqlAstTranslatorFactory() - .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); + jdbcParameters = jdbcParametersBuilder.build(); + jdbcSelect = + sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlAst ) + .translate( NO_BINDINGS, QueryOptions.NONE ); } @Override @@ -95,11 +90,9 @@ public JdbcParametersList getJdbcParameters() { @Override public PersistentCollection load(Object key, SharedSessionContractImplementor session) { - final CollectionKey collectionKey = new CollectionKey( attributeMapping.getCollectionDescriptor(), key ); - - final JdbcServices jdbcServices = session.getFactory().getJdbcServices(); + final var collectionKey = new CollectionKey( attributeMapping.getCollectionDescriptor(), key ); - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount ); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount ); int offset = jdbcParameterBindings.registerParametersForEachJdbcValue( key, attributeMapping.getKeyDescriptor(), @@ -108,14 +101,14 @@ public PersistentCollection load(Object key, SharedSessionContractImplementor ); assert offset == jdbcParameters.size(); - final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( + final var subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( session.getPersistenceContext().getBatchFetchQueue(), sqlAst, jdbcParameters, jdbcParameterBindings ); - jdbcServices.getJdbcSelectExecutor().list( + session.getFactory().getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, new CollectionLoaderSingleKeyExecutionContext( session, collectionKey, subSelectFetchableKeysHandler ), @@ -148,6 +141,5 @@ public CollectionKey getCollectionKey() { public void registerLoadingEntityHolder(EntityHolder holder) { subSelectFetchableKeysHandler.addKey( holder ); } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSubSelectFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSubSelectFetch.java index 9dc3cc36ac6b..24d7807674c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSubSelectFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionLoaderSubSelectFetch.java @@ -4,36 +4,26 @@ */ package org.hibernate.loader.ast.internal; -import java.util.Iterator; import java.util.List; import org.hibernate.LockOptions; import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.CollectionKey; -import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; -import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SubselectFetch; import org.hibernate.internal.util.NullnessUtil; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.loader.ast.spi.CollectionLoader; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.query.spi.QueryOptions; -import org.hibernate.sql.ast.SqlAstTranslatorFactory; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.internal.ResultsHelper; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; +import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; + /** * A one-time use {@link CollectionLoader} for applying a subselect fetch. * @@ -63,8 +53,8 @@ public CollectionLoaderSubSelectFetch( session.getFactory() ); - final QuerySpec querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); - final TableGroup tableGroup = querySpec.getFromClause().getRoots().get( 0 ); + final var querySpec = sqlAst.getQueryPart().getFirstQuerySpec(); + final var tableGroup = querySpec.getFromClause().getRoots().get( 0 ); attributeMapping.applySoftDeleteRestrictions( tableGroup, querySpec::applyPredicate ); } @@ -79,62 +69,52 @@ protected SelectStatement getSqlAst() { @Override public PersistentCollection load(Object triggerKey, SharedSessionContractImplementor session) { - final CollectionKey collectionKey = new CollectionKey( attributeMapping.getCollectionDescriptor(), triggerKey ); + final var collectionKey = new CollectionKey( attributeMapping.getCollectionDescriptor(), triggerKey ); - final SessionFactoryImplementor sessionFactory = session.getFactory(); - final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); - final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); - final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); - final PersistenceContext persistenceContext = session.getPersistenceContext(); + final var sessionFactory = session.getFactory(); + final var jdbcServices = sessionFactory.getJdbcServices(); + final var persistenceContext = session.getPersistenceContext(); // try to find a registered SubselectFetch - final PersistentCollection collection = persistenceContext.getCollection( collectionKey ); + final var collection = persistenceContext.getCollection( collectionKey ); attributeMapping.getCollectionDescriptor().getCollectionType().getKeyOfOwner( collection.getOwner(), session ); - final BatchFetchQueue batchFetchQueue = persistenceContext.getBatchFetchQueue(); - final EntityEntry ownerEntry = persistenceContext.getEntry( collection.getOwner() ); + final var batchFetchQueue = persistenceContext.getBatchFetchQueue(); + final var ownerEntry = persistenceContext.getEntry( collection.getOwner() ); List> subSelectFetchedCollections = null; if ( ownerEntry != null ) { - final EntityKey triggerKeyOwnerKey = ownerEntry.getEntityKey(); - final SubselectFetch registeredFetch = batchFetchQueue.getSubselect( triggerKeyOwnerKey ); + final var triggerKeyOwnerKey = ownerEntry.getEntityKey(); + final var registeredFetch = batchFetchQueue.getSubselect( triggerKeyOwnerKey ); if ( registeredFetch != null ) { - subSelectFetchedCollections = CollectionHelper.arrayList( - registeredFetch.getResultingEntityKeys().size() ); - + subSelectFetchedCollections = arrayList( registeredFetch.getResultingEntityKeys().size() ); // there was one, so we want to make sure to prepare the corresponding collection // reference for reading - final Iterator itr = registeredFetch.getResultingEntityKeys().iterator(); - while ( itr.hasNext() ) { - final EntityKey key = itr.next(); - - final PersistentCollection containedCollection = persistenceContext.getCollection( - new CollectionKey( attributeMapping.getCollectionDescriptor(), key.getIdentifier() ) - ); - + for ( var key : registeredFetch.getResultingEntityKeys() ) { + final var containedCollection = persistenceContext.getCollection( collectionKey( key ) ); if ( containedCollection != null && containedCollection != collection ) { containedCollection.beginRead(); containedCollection.beforeInitialize( getLoadable().getCollectionDescriptor(), -1 ); - subSelectFetchedCollections.add( containedCollection ); } } } } - final JdbcOperationQuerySelect jdbcSelect = sqlAstTranslatorFactory - .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( this.subselect.getLoadingJdbcParameterBindings(), QueryOptions.NONE ); + final var jdbcSelect = + jdbcServices.getJdbcEnvironment() + .getSqlAstTranslatorFactory().buildSelectTranslator( sessionFactory, sqlAst ) + .translate( subselect.getLoadingJdbcParameterBindings(), QueryOptions.NONE ); - final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( + final var subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( batchFetchQueue, sqlAst, - this.subselect.getLoadingJdbcParameters(), - this.subselect.getLoadingJdbcParameterBindings() + subselect.getLoadingJdbcParameters(), + subselect.getLoadingJdbcParameterBindings() ); jdbcServices.getJdbcSelectExecutor().list( jdbcSelect, - this.subselect.getLoadingJdbcParameterBindings(), + subselect.getLoadingJdbcParameterBindings(), new ExecutionContextWithSubselectFetchHandler( session, subSelectFetchableKeysHandler ), RowTransformerStandardImpl.instance(), ListResultsConsumer.UniqueSemantic.NONE @@ -143,25 +123,27 @@ public PersistentCollection load(Object triggerKey, SharedSessionContractImpl if ( subSelectFetchedCollections != null && ! subSelectFetchedCollections.isEmpty() ) { subSelectFetchedCollections.forEach( c -> { - if ( c.wasInitialized() ) { - return; + if ( !c.wasInitialized() ) { + final var persister = getLoadable().getCollectionDescriptor(); + c.initializeEmptyCollection( persister ); + ResultsHelper.finalizeCollectionLoading( + persistenceContext, + persister, + c, + NullnessUtil.castNonNull( c.getKey() ), + true + ); } - - c.initializeEmptyCollection( getLoadable().getCollectionDescriptor() ); - ResultsHelper.finalizeCollectionLoading( - persistenceContext, - getLoadable().getCollectionDescriptor(), - c, - NullnessUtil.castNonNull( c.getKey() ), - true - ); } ); - subSelectFetchedCollections.clear(); } return collection; } + private CollectionKey collectionKey(EntityKey key) { + return new CollectionKey( attributeMapping.getCollectionDescriptor(), key.getIdentifier() ); + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java index fc7ebf0436ca..7571ee6b0e76 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java @@ -8,25 +8,17 @@ import java.util.List; import org.hibernate.LockOptions; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.sqm.sql.FromClauseIndex; import org.hibernate.spi.NavigablePath; -import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.SqlAliasBaseManager; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.QueryLiteral; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; @@ -34,15 +26,14 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.RowTransformerArrayImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; -import org.hibernate.type.BasicType; import org.hibernate.type.StandardBasicTypes; +import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_OBJECT_ARRAY; import static org.hibernate.loader.LoaderLogging.LOADER_LOGGER; import static org.hibernate.pretty.MessageHelper.infoString; @@ -60,26 +51,25 @@ class DatabaseSnapshotExecutor { EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; - JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder( - entityDescriptor.getIdentifierMapping().getJdbcTypeCount() ); - final QuerySpec rootQuerySpec = new QuerySpec( true ); - - final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager(); - - final LoaderSqlAstCreationState state = new LoaderSqlAstCreationState( - rootQuerySpec, - sqlAliasBaseManager, - new FromClauseIndex( null ), - new LockOptions(), - (fetchParent, creationState) -> ImmutableFetchList.EMPTY, - true, - new LoadQueryInfluencers( sessionFactory ), - sessionFactory.getSqlTranslationEngine() - ); - - final NavigablePath rootPath = new NavigablePath( entityDescriptor.getEntityName() ); - - final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup( + var jdbcParametersBuilder = + JdbcParametersList.newBuilder( entityDescriptor.getIdentifierMapping().getJdbcTypeCount() ); + final var rootQuerySpec = new QuerySpec( true ); + + final var state = + new LoaderSqlAstCreationState( + rootQuerySpec, + new SqlAliasBaseManager(), + new FromClauseIndex( null ), + new LockOptions(), + (fetchParent, creationState) -> ImmutableFetchList.EMPTY, + true, + new LoadQueryInfluencers( sessionFactory ), + sessionFactory.getSqlTranslationEngine() + ); + + final var rootPath = new NavigablePath( entityDescriptor.getEntityName() ); + + final var rootTableGroup = entityDescriptor.createRootTableGroup( true, rootPath, null, @@ -94,48 +84,43 @@ class DatabaseSnapshotExecutor { // We produce the same state array as if we were creating an entity snapshot final List> domainResults = new ArrayList<>(); - final SqlExpressionResolver sqlExpressionResolver = state.getSqlExpressionResolver(); + final var sqlExpressionResolver = state.getSqlExpressionResolver(); // We just need a literal to have a result set - final BasicType resolved = sessionFactory.getTypeConfiguration() - .getBasicTypeRegistry() - .resolve( StandardBasicTypes.INTEGER ); + final var resolved = + sessionFactory.getTypeConfiguration() + .getBasicTypeRegistry() + .resolve( StandardBasicTypes.INTEGER ); final QueryLiteral queryLiteral = new QueryLiteral<>( null, resolved ); domainResults.add( queryLiteral.createDomainResult( null, state ) ); - final NavigablePath idNavigablePath = rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() ); + final var idNavigablePath = + rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() ); entityDescriptor.getIdentifierMapping().forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = rootTableGroup.resolveTableReference( - idNavigablePath, - selection.getContainingTableExpression() - ); - - final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); + final var tableReference = + rootTableGroup.resolveTableReference( idNavigablePath, + selection.getContainingTableExpression() ); + final var jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); jdbcParametersBuilder.add( jdbcParameter ); - - final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver - .resolveSqlExpression( tableReference, selection ); - + final var columnReference = + (ColumnReference) + sqlExpressionResolver.resolveSqlExpression( tableReference, selection ); rootQuerySpec.applyPredicate( - new ComparisonPredicate( - columnReference, - ComparisonOperator.EQUAL, - jdbcParameter - ) + new ComparisonPredicate( columnReference, ComparisonOperator.EQUAL, jdbcParameter ) ); } ); - this.jdbcParameters = jdbcParametersBuilder.build(); + jdbcParameters = jdbcParametersBuilder.build(); entityDescriptor.forEachAttributeMapping( attributeMapping -> { - final NavigablePath navigablePath = rootPath.append( attributeMapping.getAttributeName() ); - final DomainResult snapshotDomainResult = attributeMapping.createSnapshotDomainResult( - navigablePath, - rootTableGroup, - null, - state + final var snapshotDomainResult = + attributeMapping.createSnapshotDomainResult( + rootPath.append( attributeMapping.getAttributeName() ), + rootTableGroup, + null, + state ); if ( snapshotDomainResult != null ) { domainResults.add( snapshotDomainResult ); @@ -143,14 +128,11 @@ class DatabaseSnapshotExecutor { } ); - final SelectStatement selectStatement = new SelectStatement( rootQuerySpec, domainResults ); - - final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); - final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); - final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); - - this.jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, selectStatement ) - .translate( null, QueryOptions.NONE ); + final var selectStatement = new SelectStatement( rootQuerySpec, domainResults ); + jdbcSelect = + sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, selectStatement ) + .translate( null, QueryOptions.NONE ); } Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) { @@ -159,27 +141,29 @@ Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor sessio + infoString( entityDescriptor, id ) ); } - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( entityDescriptor.getIdentifierMapping().getJdbcTypeCount() ); - int offset = jdbcParameterBindings.registerParametersForEachJdbcValue( - id, - entityDescriptor.getIdentifierMapping(), - jdbcParameters, - session - ); + final int offset = + jdbcParameterBindings.registerParametersForEachJdbcValue( + id, + entityDescriptor.getIdentifierMapping(), + jdbcParameters, + session + ); assert offset == jdbcParameters.size(); - final List list = session.getJdbcServices().getJdbcSelectExecutor().list( - jdbcSelect, - jdbcParameterBindings, - new BaseExecutionContext( session ), - RowTransformerArrayImpl.instance(), - null, - ListResultsConsumer.UniqueSemantic.FILTER, - 1 - ); + final List list = + session.getJdbcServices().getJdbcSelectExecutor().list( + jdbcSelect, + jdbcParameterBindings, + new BaseExecutionContext( session ), + RowTransformerArrayImpl.instance(), + null, + ListResultsConsumer.UniqueSemantic.FILTER, + 1 + ); final int size = list.size(); assert size <= 1; @@ -188,11 +172,11 @@ Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor sessio return null; } else { - final Object[] entitySnapshot = (Object[]) list.get( 0 ); + final var entitySnapshot = (Object[]) list.get( 0 ); // The result of this method is treated like the entity state array which doesn't include the id // So we must exclude it from the array if ( entitySnapshot.length == 1 ) { - return ArrayHelper.EMPTY_OBJECT_ARRAY; + return EMPTY_OBJECT_ARRAY; } else { final Object[] state = new Object[entitySnapshot.length - 1]; 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 3bb3500f30d6..0d81e64b70b1 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 @@ -4,12 +4,9 @@ */ package org.hibernate.loader.ast.internal; -import java.lang.reflect.Array; -import java.util.Arrays; import java.util.Locale; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.build.AllowReflection; @@ -18,18 +15,17 @@ import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.spi.QueryOptions; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import static org.hibernate.loader.ast.internal.LoaderHelper.loadByArrayParameter; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.trimIdBatch; import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; import static org.hibernate.pretty.MessageHelper.infoString; +import static org.hibernate.sql.exec.spi.JdbcParameterBindings.NO_BINDINGS; /** * {@link SingleIdEntityLoaderSupport} implementation based on using a single @@ -43,7 +39,6 @@ public class EntityBatchLoaderArrayParam implements SqlArrayMultiKeyLoader { private final int domainBatchSize; - private final BasicEntityIdentifierMapping identifierMapping; private final JdbcMapping arrayJdbcMapping; private final JdbcParameter jdbcParameter; private final SelectStatement sqlAst; @@ -69,14 +64,13 @@ public EntityBatchLoaderArrayParam( this.domainBatchSize = domainBatchSize; if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Batch fetching enabled for entity '%s' using ARRAY strategy with batch size %s", + MULTI_KEY_LOAD_LOGGER.enabledEntityArray( entityDescriptor.getEntityName(), domainBatchSize ); } - identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); + final var identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( identifierMapping.getJdbcMapping(), identifierMapping.getJavaType().getJavaTypeClass(), @@ -96,7 +90,7 @@ public EntityBatchLoaderArrayParam( jdbcSelectOperation = sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); + .translate( NO_BINDINGS, QueryOptions.NONE ); } @Override @@ -107,8 +101,7 @@ public int getDomainBatchSize() { @AllowReflection protected Object[] resolveIdsToInitialize(Object pkValue, SharedSessionContractImplementor session) { //TODO: should this really be different to EntityBatchLoaderInPredicate impl? - final Class idType = identifierMapping.getJavaType().getJavaTypeClass(); - final Object[] idsToLoad = (Object[]) Array.newInstance( idType, domainBatchSize ); + final Object[] idsToLoad = new Object[domainBatchSize]; session.getPersistenceContextInternal().getBatchFetchQueue() .collectBatchLoadableEntityIds( domainBatchSize, @@ -128,9 +121,8 @@ protected void initializeEntities( Boolean readOnly, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Entity ids to initialize via batch fetching (%s) %s", - infoString( getLoadable(), id), - Arrays.toString( idsToInitialize ) ); + MULTI_KEY_LOAD_LOGGER.entityIdsToInitialize( + infoString( getLoadable(), id), idsToInitialize ); } removeBatchLoadableEntityKeys( idsToInitialize, session ); @@ -151,8 +143,8 @@ protected void initializeEntities( } private void removeBatchLoadableEntityKeys(Object[] idsToInitialize, SharedSessionContractImplementor session) { - final BatchFetchQueue batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); - final EntityPersister persister = getLoadable().getEntityPersister(); + final var batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); + final var persister = getLoadable().getEntityPersister(); for ( Object initializedId : idsToInitialize ) { if ( initializedId != null ) { // found or not, remove the key from the batch-fetch queue 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 8b61f83e89d1..78dc80db9297 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 @@ -4,11 +4,9 @@ */ package org.hibernate.loader.ast.internal; -import java.util.Arrays; import java.util.Locale; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SubselectFetch; @@ -16,15 +14,14 @@ import org.hibernate.loader.ast.spi.SqlInPredicateMultiKeyLoader; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.spi.QueryOptions; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER; import static org.hibernate.pretty.MessageHelper.infoString; +import static org.hibernate.sql.exec.spi.JdbcParameterBindings.NO_BINDINGS; /** * An {@link EntityBatchLoader} using one or more SQL queries, which each initialize up @@ -63,17 +60,16 @@ public EntityBatchLoaderInPredicate( .determineOptimalBatchLoadSize( idColumnCount, domainBatchSize, false ); if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Batch fetching enabled for entity '%s' using IN-predicate with batch size %s (%s)", + MULTI_KEY_LOAD_LOGGER.enabledEntityInPredicate( entityDescriptor.getEntityName(), sqlBatchSize, domainBatchSize ); } - final EntityIdentifierMapping identifierMapping = getLoadable().getIdentifierMapping(); + final var identifierMapping = getLoadable().getIdentifierMapping(); final int expectedNumberOfParameters = identifierMapping.getJdbcTypeCount() * sqlBatchSize; - final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder( expectedNumberOfParameters ); + final var builder = JdbcParametersList.newBuilder( expectedNumberOfParameters ); sqlAst = LoaderSelectBuilder.createSelect( getLoadable(), // null here means to select everything @@ -92,7 +88,7 @@ public EntityBatchLoaderInPredicate( jdbcSelectOperation = sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() .buildSelectTranslator( sessionFactory, sqlAst ) - .translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE ); + .translate( NO_BINDINGS, QueryOptions.NONE ); } @Override @@ -123,13 +119,12 @@ protected void initializeEntities( Boolean readOnly, SharedSessionContractImplementor session) { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( "Entity ids to initialize via batch fetching (%s) %s", - infoString( getLoadable(), pkValue ), - Arrays.toString(idsToInitialize) ); + MULTI_KEY_LOAD_LOGGER.entityIdsToInitialize( + infoString( getLoadable(), pkValue ), idsToInitialize ); } - final BatchFetchQueue batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); - final EntityPersister persister = getLoadable().getEntityPersister(); + final var batchFetchQueue = session.getPersistenceContextInternal().getBatchFetchQueue(); + final var persister = getLoadable().getEntityPersister(); getChunker( getLoadable().getIdentifierMapping() ) .processChunks( idsToInitialize, @@ -159,8 +154,7 @@ protected void initializeEntities( }, (startIndex) -> { if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) { - MULTI_KEY_LOAD_LOGGER.tracef( - "Processing entity batch-fetch chunk (%s) %s - %s", + MULTI_KEY_LOAD_LOGGER.processingEntityBatchFetchChunk( infoString( getLoadable(), pkValue ), startIndex, startIndex + ( sqlBatchSize - 1 ) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityConcreteTypeLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityConcreteTypeLoader.java index c9c702064122..ac770282f810 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityConcreteTypeLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityConcreteTypeLoader.java @@ -4,7 +4,6 @@ */ package org.hibernate.loader.ast.internal; -import java.util.List; import org.hibernate.LockOptions; import org.hibernate.ObjectNotFoundException; @@ -14,14 +13,11 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.spi.QueryOptions; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.BaseExecutionContext; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; @@ -43,7 +39,7 @@ public class EntityConcreteTypeLoader { public EntityConcreteTypeLoader(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; - final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder(); + final var builder = JdbcParametersList.newBuilder(); sqlSelect = LoaderSelectBuilder.createSelect( entityDescriptor, singletonList( entityDescriptor.getDiscriminatorMapping() ), @@ -59,9 +55,9 @@ public EntityConcreteTypeLoader(EntityMappingType entityDescriptor, SessionFacto } public EntityMappingType getConcreteType(Object id, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getSessionFactory(); + final var factory = session.getSessionFactory(); - final JdbcParameterBindings bindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); + final var bindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); final int offset = bindings.registerParametersForEachJdbcValue( id, entityDescriptor.getIdentifierMapping(), @@ -70,11 +66,11 @@ public EntityMappingType getConcreteType(Object id, SharedSessionContractImpleme ); assert offset == jdbcParameters.size(); - final JdbcOperationQuerySelect jdbcSelect = + final var jdbcSelect = factory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() .buildSelectTranslator( factory, sqlSelect ) .translate( bindings, QueryOptions.NONE ); - final List results = + final var results = session.getFactory().getJdbcServices().getJdbcSelectExecutor() .list( jdbcSelect, @@ -92,8 +88,8 @@ public EntityMappingType getConcreteType(Object id, SharedSessionContractImpleme else { assert results.size() == 1; final Object result = results.get( 0 ); - final MappingMetamodelImplementor mappingMetamodel = factory.getMappingMetamodel(); - final EntityPersister concreteType = + final var mappingMetamodel = factory.getMappingMetamodel(); + final var concreteType = result instanceof Class concreteClass ? mappingMetamodel.getEntityDescriptor( concreteClass ) : mappingMetamodel.getEntityDescriptor( (String) result ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java index fb56829d07e8..77fc6ac9a14a 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java @@ -27,12 +27,12 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; import org.hibernate.type.descriptor.java.JavaType; +import static java.lang.System.arraycopy; import static java.lang.reflect.Array.newInstance; import static org.hibernate.loader.LoaderLogging.LOADER_LOGGER; import static org.hibernate.pretty.MessageHelper.infoString; @@ -172,17 +172,19 @@ public static K[] normalizeKeys( assert keys.getClass().isArray(); //noinspection unchecked - final JavaType keyJavaType = (JavaType) keyPart.getJavaType(); - final Class keyClass = keyJavaType.getJavaTypeClass(); + final var keyJavaType = (JavaType) keyPart.getJavaType(); + final var keyClass = keyJavaType.getJavaTypeClass(); if ( keys.getClass().getComponentType().equals( keyClass ) ) { return keys; } final K[] typedArray = createTypedArray( keyClass, keys.length ); - final boolean coerce = !sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled(); + final boolean coerce = + !sessionFactory.getSessionFactoryOptions().getJpaCompliance() + .isLoadByIdComplianceEnabled(); if ( !coerce ) { - System.arraycopy( keys, 0, typedArray, 0, keys.length ); + arraycopy( keys, 0, typedArray, 0, keys.length ); } else { for ( int i = 0; i < keys.length; i++ ) { @@ -227,7 +229,7 @@ public static List loadByArrayParameter( assert jdbcOperation != null; assert jdbcParameter != null; - final JdbcParameterBindings bindings = new JdbcParameterBindingsImpl( 1); + final var bindings = new JdbcParameterBindingsImpl( 1); bindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( arrayJdbcMapping, idsToInitialize ) ); return session.getJdbcServices().getJdbcSelectExecutor().list( jdbcOperation, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index d247d7c6a9d3..654d9aaedfe4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -6,26 +6,18 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.function.Consumer; import org.hibernate.LockOptions; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; -import org.hibernate.engine.profile.FetchProfile; -import org.hibernate.engine.spi.CascadeStyle; -import org.hibernate.engine.spi.CascadingAction; -import org.hibernate.engine.spi.EffectiveEntityGraph; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SubselectFetch; -import org.hibernate.graph.GraphSemantic; -import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.loader.ast.spi.Loadable; import org.hibernate.loader.ast.spi.Loader; import org.hibernate.metamodel.CollectionClassification; -import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityValuedModelPart; @@ -35,7 +27,6 @@ import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.Restrictable; -import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.ValuedModelPart; import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping; import org.hibernate.metamodel.mapping.internal.SimpleForeignKeyDescriptor; @@ -52,16 +43,13 @@ import org.hibernate.sql.ast.spi.SqlAliasBaseManager; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationState; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.from.PluralTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer; -import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; import org.hibernate.sql.ast.tree.predicate.InArrayPredicate; import org.hibernate.sql.ast.tree.predicate.InListPredicate; @@ -77,7 +65,6 @@ import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; -import org.hibernate.sql.results.graph.FetchableContainer; import org.hibernate.sql.results.graph.collection.internal.CollectionDomainResult; import org.hibernate.sql.results.graph.entity.EntityValuedFetchable; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; @@ -117,7 +104,7 @@ public static SelectStatement createSelectByUniqueKey( LockOptions lockOptions, Consumer jdbcParameterConsumer, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( + final var process = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), loadable, partsToSelect, @@ -130,7 +117,6 @@ public static SelectStatement createSelectByUniqueKey( true, jdbcParameterConsumer ); - return process.generateSelect(); } @@ -144,7 +130,7 @@ public static SelectStatement createSelectBySingleArrayParameter( LockOptions lockOptions, JdbcParameter jdbcArrayParameter, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder builder = new LoaderSelectBuilder( + final var builder = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), loadable, null, @@ -158,14 +144,14 @@ public static SelectStatement createSelectBySingleArrayParameter( null ); - final QuerySpec rootQuerySpec = new QuerySpec( true ); - final LoaderSqlAstCreationState sqlAstCreationState = builder.createSqlAstCreationState( rootQuerySpec ); + final var rootQuerySpec = new QuerySpec( true ); + final var sqlAstCreationState = builder.createSqlAstCreationState( rootQuerySpec ); - final NavigablePath rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); - final TableGroup rootTableGroup = + final var rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); + final var rootTableGroup = builder.buildRootTableGroup( rootNavigablePath, rootQuerySpec, sqlAstCreationState ); - final DomainResult domainResult = loadable.createDomainResult( + final var domainResult = loadable.createDomainResult( rootNavigablePath, rootTableGroup, null, @@ -183,7 +169,6 @@ public static SelectStatement createSelectBySingleArrayParameter( sqlAstCreationState ); - if ( loadable instanceof PluralAttributeMapping pluralAttributeMapping ) { builder.applyFiltering( rootQuerySpec, rootTableGroup, pluralAttributeMapping, sqlAstCreationState ); builder.applyOrdering( rootQuerySpec, rootTableGroup, pluralAttributeMapping, sqlAstCreationState ); @@ -203,15 +188,16 @@ private static void applyArrayParamRestriction( JdbcParameter jdbcArrayParameter, LoaderSqlAstCreationState sqlAstCreationState) { assert restrictedPart.getJdbcTypeCount() == 1; - final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); - final SelectableMapping restrictedPartMapping = restrictedPart.getSelectable( 0 ); - final NavigablePath restrictionPath = + final var sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); + final var restrictedPartMapping = restrictedPart.getSelectable( 0 ); + final var restrictionPath = rootNavigablePath.append( restrictedPart.getNavigableRole().getNavigableName() ); - final TableReference tableReference = + final var tableReference = rootTableGroup.resolveTableReference( restrictionPath, restrictedPartMapping.getContainingTableExpression() ); - final ColumnReference columnRef = (ColumnReference) - sqlExpressionResolver.resolveSqlExpression( tableReference, restrictedPartMapping ); + final var columnRef = + (ColumnReference) + sqlExpressionResolver.resolveSqlExpression( tableReference, restrictedPartMapping ); rootQuerySpec.applyPredicate( new InArrayPredicate( columnRef, jdbcArrayParameter ) ); } @@ -239,7 +225,7 @@ public static SelectStatement createSelect( LockOptions lockOptions, Consumer jdbcParameterConsumer, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( + final var process = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), loadable, partsToSelect, @@ -263,7 +249,7 @@ public static SelectStatement createSelect( LockOptions lockOptions, Consumer jdbcParameterConsumer, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( + final var process = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), loadable, partsToSelect, @@ -290,7 +276,7 @@ static SelectStatement createSelect( LockOptions lockOptions, Consumer jdbcParameterConsumer, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( + final var process = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), loadable, partsToSelect, @@ -328,7 +314,7 @@ public static SelectStatement createSubSelectFetchSelect( LockOptions lockOptions, Consumer jdbcParameterConsumer, SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( + final var process = new LoaderSelectBuilder( sessionFactory.getSqlTranslationEngine(), attributeMapping, null, @@ -339,7 +325,6 @@ public static SelectStatement createSubSelectFetchSelect( lockOptions, jdbcParameterConsumer ); - return process.generateSelect( subselect ); } @@ -443,13 +428,13 @@ private static boolean determineWhetherToForceIdSelection(int numberOfKeysToLoad } if ( restrictedParts.size() == 1 ) { - final ModelPart restrictedPart = restrictedParts.get( 0 ); + final var restrictedPart = restrictedParts.get( 0 ); if ( Objects.equals( restrictedPart.getPartName(), NaturalIdMapping.PART_NAME ) ) { return true; } } - for ( ModelPart restrictedPart : restrictedParts ) { + for ( var restrictedPart : restrictedParts ) { if ( restrictedPart instanceof ForeignKeyDescriptor || restrictedPart instanceof NonAggregatedIdentifierMapping ) { return true; @@ -463,10 +448,10 @@ private static EntityGraphTraversalState determineGraphTraversalState( LoadQueryInfluencers loadQueryInfluencers, JpaMetamodel jpaMetamodel) { if ( loadQueryInfluencers != null ) { - final EffectiveEntityGraph effectiveEntityGraph = loadQueryInfluencers.getEffectiveEntityGraph(); + final var effectiveEntityGraph = loadQueryInfluencers.getEffectiveEntityGraph(); if ( effectiveEntityGraph != null ) { - final GraphSemantic graphSemantic = effectiveEntityGraph.getSemantic(); - final RootGraphImplementor rootGraph = effectiveEntityGraph.getGraph(); + final var graphSemantic = effectiveEntityGraph.getSemantic(); + final var rootGraph = effectiveEntityGraph.getGraph(); if ( graphSemantic != null && rootGraph != null ) { return new StandardEntityGraphTraversalStateImpl( graphSemantic, rootGraph, jpaMetamodel ); } @@ -476,22 +461,22 @@ private static EntityGraphTraversalState determineGraphTraversalState( } private SelectStatement generateSelect() { - final NavigablePath rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); + final var rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); - final QuerySpec rootQuerySpec = new QuerySpec( true ); - final LoaderSqlAstCreationState sqlAstCreationState = createSqlAstCreationState( rootQuerySpec ); + final var rootQuerySpec = new QuerySpec( true ); + final var sqlAstCreationState = createSqlAstCreationState( rootQuerySpec ); - final TableGroup rootTableGroup = buildRootTableGroup( rootNavigablePath, rootQuerySpec, sqlAstCreationState ); + final var rootTableGroup = buildRootTableGroup( rootNavigablePath, rootQuerySpec, sqlAstCreationState ); final List> domainResults; if ( partsToSelect != null && !partsToSelect.isEmpty() ) { domainResults = buildRequestedDomainResults( rootNavigablePath, sqlAstCreationState, rootTableGroup ); } - else if ( this.cachedDomainResult != null ) { - domainResults = singletonList( this.cachedDomainResult ); + else if ( cachedDomainResult != null ) { + domainResults = singletonList( cachedDomainResult ); } else { - final DomainResult domainResult = loadable.createDomainResult( + final var domainResult = loadable.createDomainResult( rootNavigablePath, rootTableGroup, null, @@ -500,7 +485,7 @@ else if ( this.cachedDomainResult != null ) { domainResults = singletonList( domainResult ); } - for ( ModelPart restrictedPart : restrictedParts ) { + for ( var restrictedPart : restrictedParts ) { applyRestriction( rootQuerySpec, rootNavigablePath, @@ -527,11 +512,11 @@ private List> buildRequestedDomainResults( NavigablePath rootNavigablePath, LoaderSqlAstCreationState sqlAstCreationState, TableGroup rootTableGroup) { final List> domainResults; domainResults = new ArrayList<>( partsToSelect.size() ); - for ( ModelPart part : partsToSelect ) { - final NavigablePath navigablePath = rootNavigablePath.append( part.getPartName() ); + for ( var part : partsToSelect ) { + final var navigablePath = rootNavigablePath.append( part.getPartName() ); final TableGroup tableGroup; if ( part instanceof TableGroupJoinProducer tableGroupJoinProducer ) { - final TableGroupJoin tableGroupJoin = tableGroupJoinProducer.createTableGroupJoin( + final var tableGroupJoin = tableGroupJoinProducer.createTableGroupJoin( navigablePath, rootTableGroup, null, @@ -563,7 +548,7 @@ private List> buildRequestedDomainResults( private TableGroup buildRootTableGroup( NavigablePath rootNavigablePath, QuerySpec rootQuerySpec, LoaderSqlAstCreationState sqlAstCreationState) { - final TableGroup rootTableGroup = loadable.createRootTableGroup( + final var rootTableGroup = loadable.createRootTableGroup( true, rootNavigablePath, null, @@ -599,33 +584,31 @@ private void applyRestriction( int numberColumns, Consumer jdbcParameterConsumer, LoaderSqlAstCreationState sqlAstCreationState) { - final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); - final NavigablePath navigablePath = + final var sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); + final var navigablePath = rootNavigablePath.append( restrictedPart.getNavigableRole().getNavigableName() ); if ( numberColumns == 1 ) { restrictedPart.forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = + final var tableReference = rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ); - final ColumnReference columnRef = + final var columnRef = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( tableReference, selection ); if ( numberOfKeysToLoad == 1 ) { - final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); + final var jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); jdbcParameterConsumer.accept( jdbcParameter ); - rootQuerySpec.applyPredicate( new ComparisonPredicate( columnRef, ComparisonOperator.EQUAL, jdbcParameter ) ); } else { - final InListPredicate predicate = new InListPredicate( columnRef ); + final var predicate = new InListPredicate( columnRef ); for ( int i = 0; i < numberOfKeysToLoad; i++ ) { for ( int j = 0; j < numberColumns; j++ ) { - final JdbcParameter jdbcParameter = - new JdbcParameterImpl( columnRef.getJdbcMapping() ); + final var jdbcParameter = new JdbcParameterImpl( columnRef.getJdbcMapping() ); jdbcParameterConsumer.accept( jdbcParameter ); predicate.addExpression( jdbcParameter ); } @@ -638,10 +621,9 @@ private void applyRestriction( } else { final List columnReferences = new ArrayList<>( numberColumns ); - restrictedPart.forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = + final var tableReference = rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ); columnReferences.add( @@ -719,15 +701,17 @@ private void applyOrdering( TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping, SqlAstCreationState astCreationState) { - if ( pluralAttributeMapping.getOrderByFragment() != null ) { - applyOrdering( querySpec, tableGroup, pluralAttributeMapping.getOrderByFragment(), astCreationState ); + final var orderByFragment = pluralAttributeMapping.getOrderByFragment(); + if ( orderByFragment != null ) { + applyOrdering( querySpec, tableGroup, orderByFragment, astCreationState ); } - if ( pluralAttributeMapping.getManyToManyOrderByFragment() != null ) { + final var manyToManyOrderByFragment = pluralAttributeMapping.getManyToManyOrderByFragment(); + if ( manyToManyOrderByFragment != null ) { applyOrdering( querySpec, tableGroup, - pluralAttributeMapping.getManyToManyOrderByFragment(), + manyToManyOrderByFragment, astCreationState ); } @@ -742,11 +726,10 @@ private void applyOrdering( } private ImmutableFetchList visitFetches(FetchParent fetchParent, LoaderSqlAstCreationState creationState) { - final ImmutableFetchList.Builder fetches = - new ImmutableFetchList.Builder( fetchParent.getReferencedMappingContainer() ); - final FetchableConsumer processor = createFetchableConsumer( fetchParent, creationState, fetches ); + final var fetches = new ImmutableFetchList.Builder( fetchParent.getReferencedMappingContainer() ); + final var processor = createFetchableConsumer( fetchParent, creationState, fetches ); - final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer(); + final var referencedMappingContainer = fetchParent.getReferencedMappingContainer(); if ( fetchParent.getNavigablePath().getParent() != null ) { final int size = referencedMappingContainer.getNumberOfKeyFetchables(); for ( int i = 0; i < size; i++ ) { @@ -784,7 +767,7 @@ private boolean isBag(Fetchable fetchable) { } private boolean isPluralAttributeMapping(Fetchable fetchable) { - final AttributeMapping attributeMapping = fetchable.asAttributeMapping(); + final var attributeMapping = fetchable.asAttributeMapping(); return attributeMapping != null && attributeMapping.isPluralAttributeMapping(); } @@ -802,26 +785,11 @@ private FetchableConsumer createFetchableConsumer( return; } - final NavigablePath fetchablePath; - - if ( isKeyFetchable ) { - final EntityIdentifierMapping identifierMapping = getEntityIdentifierMapping( fetchParent ); - if ( identifierMapping != null ) { - fetchablePath = new EntityIdentifierNavigablePath( - fetchParent.getNavigablePath(), - attributeName( identifierMapping ) - ); - } - else { - fetchablePath = fetchParent.resolveNavigablePath( fetchable ); - } - } - else { - fetchablePath = fetchParent.resolveNavigablePath( fetchable ); - } + final var fetchablePath = getFetchablePath( fetchParent, fetchable, isKeyFetchable ); - FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming(); - boolean joined = fetchable.getMappedFetchOptions().getStyle() == FetchStyle.JOIN; + final var mappedFetchOptions = fetchable.getMappedFetchOptions(); + var fetchTiming = mappedFetchOptions.getTiming(); + boolean joined = mappedFetchOptions.getStyle() == FetchStyle.JOIN; boolean explicitFetch = false; EntityGraphTraversalState.TraversalResult traversalResult = null; @@ -832,7 +800,7 @@ private FetchableConsumer createFetchableConsumer( // 'entity graph' takes precedence over 'fetch profile' if ( entityGraphTraversalState != null ) { traversalResult = entityGraphTraversalState.traverse( fetchParent, fetchable, isKeyFetchable ); - final EntityGraphTraversalState.FetchStrategy fetchStrategy = traversalResult.getFetchStrategy(); + final var fetchStrategy = traversalResult.getFetchStrategy(); if ( fetchStrategy != null ) { fetchTiming = fetchStrategy.getFetchTiming(); joined = fetchStrategy.isJoined(); @@ -844,10 +812,8 @@ else if ( loadQueryInfluencers.hasEnabledFetchProfiles() ) { if ( fetchTiming != FetchTiming.IMMEDIATE || fetchable.incrementFetchDepth() ) { final String fetchableRole = fetchable.getNavigableRole().getFullPath(); for ( String enabledFetchProfileName : loadQueryInfluencers.getEnabledFetchProfileNames() ) { - final FetchProfile enabledFetchProfile = - creationContext.getFetchProfile( enabledFetchProfileName ); - final org.hibernate.engine.profile.Fetch profileFetch = - enabledFetchProfile.getFetchByRole( fetchableRole ); + final var enabledFetchProfile = creationContext.getFetchProfile( enabledFetchProfileName ); + final var profileFetch = enabledFetchProfile.getFetchByRole( fetchableRole ); if ( profileFetch != null ) { fetchTiming = profileFetch.getTiming(); joined = joined || profileFetch.getMethod() == FetchStyle.JOIN; @@ -857,11 +823,12 @@ else if ( loadQueryInfluencers.hasEnabledFetchProfiles() ) { } } else if ( loadQueryInfluencers.getEnabledCascadingFetchProfile() != null ) { - final CascadeStyle cascadeStyle = - fetchable.asAttributeMapping() != null - ? fetchable.asAttributeMapping().getAttributeMetadata().getCascadeStyle() + final var attributeMapping = fetchable.asAttributeMapping(); + final var cascadeStyle = + attributeMapping != null + ? attributeMapping.getAttributeMetadata().getCascadeStyle() : null; - final CascadingAction cascadingAction = + final var cascadingAction = loadQueryInfluencers.getEnabledCascadingFetchProfile().getCascadingAction(); if ( cascadeStyle == null || cascadeStyle.doCascade( cascadingAction ) ) { fetchTiming = FetchTiming.IMMEDIATE; @@ -938,6 +905,24 @@ else if ( fetchDepth > maximumFetchDepth + 1 ) { }; } + private static NavigablePath getFetchablePath(FetchParent fetchParent, Fetchable fetchable, boolean isKeyFetchable) { + if ( isKeyFetchable ) { + final var identifierMapping = getEntityIdentifierMapping( fetchParent ); + if ( identifierMapping != null ) { + return new EntityIdentifierNavigablePath( + fetchParent.getNavigablePath(), + attributeName( identifierMapping ) + ); + } + else { + return fetchParent.resolveNavigablePath( fetchable ); + } + } + else { + return fetchParent.resolveNavigablePath( fetchable ); + } + } + private static EntityIdentifierMapping getEntityIdentifierMapping(FetchParent fetchParent) { if ( fetchParent instanceof BiDirectionalFetch parentAsBiDirectionalFetch ) { return parentAsBiDirectionalFetch.getFetchedMapping() instanceof EntityValuedFetchable entityFetchable @@ -996,15 +981,15 @@ private SelectStatement generateSelect(SubselectFetch subselect) { assert loadable instanceof PluralAttributeMapping; - final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable; + final var attributeMapping = (PluralAttributeMapping) loadable; - final QuerySpec rootQuerySpec = new QuerySpec( true ); + final var rootQuerySpec = new QuerySpec( true ); - final NavigablePath rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); + final var rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); // We need to initialize the acronymMap based on subselect.getLoadingSqlAst() to avoid alias collisions - final Map tableReferences = AliasCollector.getTableReferences( subselect.getLoadingSqlAst() ); - final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState( + final var tableReferences = AliasCollector.getTableReferences( subselect.getLoadingSqlAst() ); + final var sqlAstCreationState = new LoaderSqlAstCreationState( rootQuerySpec, new SqlAliasBaseManager( tableReferences.keySet() ), new SimpleFromClauseAccessImpl(), @@ -1015,12 +1000,12 @@ private SelectStatement generateSelect(SubselectFetch subselect) { creationContext ); - final TableGroup rootTableGroup = buildRootTableGroup( rootNavigablePath, rootQuerySpec, sqlAstCreationState ); + final var rootTableGroup = buildRootTableGroup( rootNavigablePath, rootQuerySpec, sqlAstCreationState ); // generate and apply the restriction applySubSelectRestriction( rootQuerySpec, rootTableGroup, subselect, sqlAstCreationState ); - // NOTE : no need to check - we are explicitly processing a plural-attribute + // NOTE: no need to check - we are explicitly processing a plural-attribute applyFiltering( rootQuerySpec, rootTableGroup, attributeMapping, sqlAstCreationState ); applyOrdering( rootQuerySpec, rootTableGroup, attributeMapping, sqlAstCreationState ); @@ -1050,15 +1035,14 @@ private void applySubSelectRestriction( LoaderSqlAstCreationState sqlAstCreationState) { assert loadable instanceof PluralAttributeMapping; - final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable; - final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor(); + final var attributeMapping = (PluralAttributeMapping) loadable; + final var fkDescriptor = attributeMapping.getKeyDescriptor(); final Expression fkExpression; - if ( !fkDescriptor.isEmbedded() ) { assert fkDescriptor instanceof SimpleForeignKeyDescriptor; - final SimpleForeignKeyDescriptor simpleFkDescriptor = (SimpleForeignKeyDescriptor) fkDescriptor; - final TableReference tableReference = + final var simpleFkDescriptor = (SimpleForeignKeyDescriptor) fkDescriptor; + final var tableReference = rootTableGroup.resolveTableReference( null, fkDescriptor, simpleFkDescriptor.getContainingTableExpression() ); fkExpression = @@ -1069,7 +1053,7 @@ private void applySubSelectRestriction( final List columnReferences = new ArrayList<>( fkDescriptor.getJdbcTypeCount() ); fkDescriptor.forEachSelectable( (columnIndex, selection) -> { - final TableReference tableReference = + final var tableReference = rootTableGroup.resolveTableReference( null, fkDescriptor, selection.getContainingTableExpression() ); columnReferences.add( @@ -1079,7 +1063,6 @@ private void applySubSelectRestriction( ); } ); - fkExpression = new SqlTuple( columnReferences, fkDescriptor ); } @@ -1096,20 +1079,20 @@ private QueryPart generateSubSelect( PluralAttributeMapping attributeMapping, SubselectFetch subselect, LoaderSqlAstCreationState creationState) { - final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor(); - final QuerySpec subQuery = new QuerySpec( false ); - final QuerySpec loadingSqlAst = subselect.getLoadingSqlAst(); - final TableGroup ownerTableGroup = subselect.getOwnerTableGroup(); + final var fkDescriptor = attributeMapping.getKeyDescriptor(); + final var subQuery = new QuerySpec( false ); + final var loadingSqlAst = subselect.getLoadingSqlAst(); + final var ownerTableGroup = subselect.getOwnerTableGroup(); // transfer the from-clause loadingSqlAst.getFromClause().visitRoots( subQuery.getFromClause()::addRoot ); - final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver(); + final var sqlExpressionResolver = creationState.getSqlExpressionResolver(); fkDescriptor.visitTargetSelectables( (valuesPosition, selection) -> { // for each column, resolve a SqlSelection and add it to the sub-query select-clause - final TableReference tableReference = + final var tableReference = ownerTableGroup.resolveTableReference( null, fkDescriptor, selection.getContainingTableExpression() ); subQuery.getSelectClause() @@ -1127,11 +1110,11 @@ private QueryPart generateSubSelect( private void registerPluralTableGroupParts(FromClauseAccess fromClauseAccess, TableGroup tableGroup) { if ( tableGroup instanceof PluralTableGroup pluralTableGroup ) { if ( pluralTableGroup.getElementTableGroup() != null ) { - final TableGroup elementTableGroup = pluralTableGroup.getElementTableGroup(); + final var elementTableGroup = pluralTableGroup.getElementTableGroup(); fromClauseAccess.registerTableGroup( elementTableGroup.getNavigablePath(), elementTableGroup ); } if ( pluralTableGroup.getIndexTableGroup() != null ) { - final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup(); + final var indexTableGroup = pluralTableGroup.getIndexTableGroup(); fromClauseAccess.registerTableGroup( indexTableGroup.getNavigablePath(), indexTableGroup ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSqlAstCreationState.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSqlAstCreationState.java index 81ef1f3e5d53..6f6e364364e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSqlAstCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSqlAstCreationState.java @@ -179,7 +179,7 @@ public ImmutableFetchList visitFetches(FetchParent fetchParent) { @Override public R withNestedFetchParent(FetchParent fetchParent, Function action) { - final FetchParent nestingFetchParent = processingState.getNestingFetchParent(); + final var nestingFetchParent = processingState.getNestingFetchParent(); processingState.setNestingFetchParent( fetchParent ); final R result = action.apply( fetchParent ); processingState.setNestingFetchParent( nestingFetchParent ); 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 249536c18fe4..8b8fa2b7e2a2 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 @@ -20,14 +20,10 @@ import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptionsAdapter; -import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.tree.expression.JdbcParameter; -import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcParameterImpl; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ManagedResultConsumer; @@ -56,7 +52,7 @@ public MultiIdEntityLoaderArrayParam( EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { super( entityDescriptor, sessionFactory ); - final Class idClass = identifierMapping.getJavaType().getJavaTypeClass(); + final var idClass = identifierMapping.getJavaType().getJavaTypeClass(); idArray = (Object[]) Array.newInstance( idClass, 0 ); arrayJdbcMapping = resolveArrayJdbcMapping( getIdentifierMapping().getJdbcMapping(), idClass, getSessionFactory() ); @@ -83,26 +79,33 @@ protected void loadEntitiesById( LockOptions lockOptions, MultiIdLoadOptions loadOptions, SharedSessionContractImplementor session) { - final SelectStatement sqlAst = createSelectBySingleArrayParameter( - getLoadable(), - getIdentifierMapping(), - session.getLoadQueryInfluencers(), - lockOptions, - jdbcParameter, - getSessionFactory() - ); - - final JdbcParameterBindings bindings = new JdbcParameterBindingsImpl(1); - bindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( arrayJdbcMapping, toIdArray( idsInBatch ) ) ); - - final SqlAstTranslator sqlAstTranslator = getSqlAstTranslatorFactory() - .buildSelectTranslator( getSessionFactory(), sqlAst ); - final JdbcOperationQuerySelect jdbcOperation = sqlAstTranslator.translate( NO_BINDINGS, new QueryOptionsAdapter() { - @Override - public LockOptions getLockOptions() { - return lockOptions; - } - } ); + final var sqlAst = + createSelectBySingleArrayParameter( + getLoadable(), + getIdentifierMapping(), + session.getLoadQueryInfluencers(), + lockOptions, + jdbcParameter, + getSessionFactory() + ); + + final var bindings = new JdbcParameterBindingsImpl(1); + bindings.addBinding( jdbcParameter, + new JdbcParameterBindingImpl( arrayJdbcMapping, toIdArray( idsInBatch ) ) ); + + final var sqlAstTranslator = + getSqlAstTranslatorFactory() + .buildSelectTranslator( getSessionFactory(), sqlAst ); + final var jdbcOperation = + sqlAstTranslator.translate( + NO_BINDINGS, + new QueryOptionsAdapter() { + @Override + public LockOptions getLockOptions() { + return lockOptions; + } + } + ); getJdbcSelectExecutor().executeQuery( jdbcOperation, @@ -134,16 +137,17 @@ protected void loadEntitiesWithUnresolvedIds( LockOptions lockOptions, List results, SharedSessionContractImplementor session) { - final SelectStatement sqlAst = createSelectBySingleArrayParameter( - getLoadable(), - getIdentifierMapping(), - session.getLoadQueryInfluencers(), - lockOptions, - jdbcParameter, - getSessionFactory() - ); - - final JdbcOperationQuerySelect jdbcSelectOperation = + final var sqlAst = + createSelectBySingleArrayParameter( + getLoadable(), + getIdentifierMapping(), + session.getLoadQueryInfluencers(), + lockOptions, + jdbcParameter, + getSessionFactory() + ); + + final var jdbcSelectOperation = getSqlAstTranslatorFactory().buildSelectTranslator( getSessionFactory(), sqlAst ) .translate( NO_BINDINGS, QueryOptions.NONE ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderInPredicate.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderInPredicate.java index 4bf0e4c074e1..487fd91b074d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderInPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderInPredicate.java @@ -7,7 +7,6 @@ import java.util.List; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -100,24 +99,25 @@ private List performRegularMultiLoad( // getLoadable().getEntityName(), numberOfIdsInBatch ); // } - final JdbcParametersList.Builder jdbcParametersBuilder = + final var jdbcParametersBuilder = JdbcParametersList.newBuilder( numberOfIdsInBatch * idJdbcTypeCount ); - final SelectStatement sqlAst = createSelect( - getLoadable(), - // null here means to select everything - null, - getLoadable().getIdentifierMapping(), - null, - numberOfIdsInBatch, - session.getLoadQueryInfluencers(), - lockOptions, - jdbcParametersBuilder::add, - getSessionFactory() - ); - - final JdbcParametersList jdbcParameters = jdbcParametersBuilder.build(); - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); + final var sqlAst = + createSelect( + getLoadable(), + // null here means to select everything + null, + getLoadable().getIdentifierMapping(), + null, + numberOfIdsInBatch, + session.getLoadQueryInfluencers(), + lockOptions, + jdbcParametersBuilder::add, + getSessionFactory() + ); + + final var jdbcParameters = jdbcParametersBuilder.build(); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); int offset = 0; for ( int i = 0; i < numberOfIdsInBatch; i++ ) { offset += jdbcParameterBindings.registerParametersForEachJdbcValue( @@ -159,7 +159,7 @@ private SubselectFetch.RegistrationHandler fetchableKeysHandler( SelectStatement sqlAst, JdbcParametersList jdbcParameters, JdbcParameterBindings jdbcParameterBindings) { - final BatchFetchQueue batchFetchQueue = session.getPersistenceContext().getBatchFetchQueue(); + final var batchFetchQueue = session.getPersistenceContext().getBatchFetchQueue(); return session.getLoadQueryInfluencers().hasSubselectLoadableCollections( getLoadable().getEntityPersister() ) ? createRegistrationHandler( batchFetchQueue, sqlAst, jdbcParameters, jdbcParameterBindings ) : null; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadChunker.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadChunker.java index fb93af668adf..18b8bbc55bf6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadChunker.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadChunker.java @@ -91,7 +91,6 @@ public void processChunks( int start = 0; while ( numberOfKeysLeft > 0 ) { processChunk( keys, start, sqlExecutionContextCreator, keyCollector, startListener, boundaryListener, session ); - start += chunkSize; numberOfKeysLeft -= chunkSize; } @@ -108,7 +107,7 @@ private void processChunk( startListener.chunkStartNotification( startIndex ); final int parameterCount = chunkSize * keyColumnCount; - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( parameterCount ); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( parameterCount ); int nonNullCounter = 0; int bindCount = 0; @@ -140,22 +139,20 @@ private void processChunk( } assert bindCount == jdbcParameters.size(); - if ( nonNullCounter == 0 ) { - // there are no non-null keys in the chunk - return; - } + if ( nonNullCounter != 0 ) { + session.getFactory().getJdbcServices().getJdbcSelectExecutor().executeQuery( + jdbcSelect, + jdbcParameterBindings, + sqlExecutionContextCreator.createContext( jdbcParameterBindings, session ), + RowTransformerStandardImpl.instance(), + null, + nonNullCounter, + ManagedResultConsumer.INSTANCE + ); - session.getFactory().getJdbcServices().getJdbcSelectExecutor().executeQuery( - jdbcSelect, - jdbcParameterBindings, - sqlExecutionContextCreator.createContext( jdbcParameterBindings, session ), - RowTransformerStandardImpl.instance(), - null, - nonNullCounter, - ManagedResultConsumer.INSTANCE - ); - - boundaryListener.chunkBoundaryNotification( startIndex, nonNullCounter ); + boundaryListener.chunkBoundaryNotification( startIndex, nonNullCounter ); + } + // otherwise, there are no non-null keys in the chunk } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java index 5c6bbd5d45b1..e346cd182e45 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java @@ -35,9 +35,10 @@ public static JdbcMapping resolveArrayJdbcMapping( } final var typeConfiguration = sessionFactory.getTypeConfiguration(); - final var javaTypeRegistry = typeConfiguration.getJavaTypeRegistry(); - final var rawArrayJavaType = javaTypeRegistry.resolveArrayDescriptor( elementClass ); + final var rawArrayJavaType = + typeConfiguration.getJavaTypeRegistry() + .resolveArrayDescriptor( elementClass ); if ( !(rawArrayJavaType instanceof BasicPluralJavaType arrayJavaType ) ) { throw new IllegalArgumentException( "Expecting BasicPluralJavaType for array class '" + elementClass.getTypeName() + "[]', but got '" diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadLogging.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadLogging.java index 31f913c01c72..450395721f85 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadLogging.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadLogging.java @@ -7,11 +7,20 @@ import org.hibernate.Internal; import org.hibernate.internal.log.SubSystemLogging; +import org.jboss.logging.BasicLogger; import org.jboss.logging.Logger; +import org.jboss.logging.annotations.LogMessage; +import org.jboss.logging.annotations.Message; +import org.jboss.logging.annotations.MessageLogger; +import org.jboss.logging.annotations.ValidIdRange; + +import java.lang.invoke.MethodHandles; + +import static org.jboss.logging.Logger.Level.TRACE; /** * Logging related to loading a {@linkplain org.hibernate.loader.ast.spi.Loadable loadable} - * by multiple "keys". The key can be primary, foreign or natural. + * by multiple "keys". The key can be primary, foreign or natural. * * @see org.hibernate.annotations.BatchSize * @see org.hibernate.Session#byMultipleIds @@ -19,13 +28,78 @@ * * @author Steve Ebersole */ +@MessageLogger(projectCode = "HHH") +@ValidIdRange(min = 90006101, max = 90007000) @SubSystemLogging( name = MultiKeyLoadLogging.LOGGER_NAME, description = "Logging related to multi-key loading of entity and collection references" ) @Internal -public interface MultiKeyLoadLogging { +public interface MultiKeyLoadLogging extends BasicLogger { String LOGGER_NAME = SubSystemLogging.BASE + ".loader.multi"; - Logger MULTI_KEY_LOAD_LOGGER = Logger.getLogger( LOGGER_NAME ); + MultiKeyLoadLogging MULTI_KEY_LOAD_LOGGER = Logger.getMessageLogger( MethodHandles.lookup(), MultiKeyLoadLogging.class, LOGGER_NAME ); + + // Enablement messages + @LogMessage(level = TRACE) + @Message(id = 90006101, + value = "Batch fetching enabled for collection '%s' using ARRAY strategy with batch size %s") + void enabledCollectionArray(String role, int domainBatchSize); + + @LogMessage(level = TRACE) + @Message(id = 90006102, + value = "Batch fetching enabled for collection '%s' using IN-predicate with batch size %s (%s)") + void enabledCollectionInPredicate(String role, int sqlBatchSize, int domainBatchSize); + + @LogMessage(level = TRACE) + @Message(id = 90006103, + value = "Batch fetching enabled for entity '%s' using ARRAY strategy with batch size %s") + void enabledEntityArray(String entityName, int domainBatchSize); + + @LogMessage(level = TRACE) + @Message(id = 90006104, + value = "Batch fetching enabled for entity '%s' using IN-predicate with batch size %s (%s)") + void enabledEntityInPredicate(String entityName, int sqlBatchSize, int domainBatchSize); + + // Start operations + @LogMessage(level = TRACE) + @Message(id = 90006110, value = "Batch fetching collection: %s") + void batchFetchingCollection(String collectionInfoString); + + @LogMessage(level = TRACE) + @Message(id = 90006111, value = "Finishing initializing batch fetched collection: %s") + void finishingInitializingBatchFetchedCollection(String collectionInfoString); + + @LogMessage(level = TRACE) + @Message(id = 90006112, value = "Batch fetching entity: %s") + void batchFetchingEntity(String entityInfoString); + + @LogMessage(level = TRACE) + @Message(id = 90006113, value = "Unordered batch load starting: %s") + void unorderedBatchLoadStarting(String entityName); + + @LogMessage(level = TRACE) + @Message(id = 90006114, value = "Ordered MultiLoad starting: %s") + void orderedMultiLoadStarting(String entityName); + + // Details + @LogMessage(level = TRACE) + @Message(id = 90006120, value = "Collection keys to initialize via batch fetching (%s) %s") + void collectionKeysToInitialize(String collectionInfoString, Object[] keysToInitialize); + + @LogMessage(level = TRACE) + @Message(id = 90006121, value = "Entity ids to initialize via batch fetching (%s) %s") + void entityIdsToInitialize(String entityInfoString, Object[] idsToInitialize); + + @LogMessage(level = TRACE) + @Message(id = 90006122, value = "Processing entity batch-fetch chunk (%s) %s - %s") + void processingEntityBatchFetchChunk(String entityInfoString, int startIndex, int endIndex); + + @LogMessage(level = TRACE) + @Message(id = 90006123, value = "Processing collection batch fetch chunk (%s) %s - %s") + void processingCollectionBatchFetchChunk(String collectionInfoString, int startIndex, int endIndex); + + @LogMessage(level = TRACE) + @Message(id = 90006124, value = "Finishing collection batch fetch chunk (%s) %s - %s (%s)") + void finishingCollectionBatchFetchChunk(String collectionInfoString, int startIndex, int endIndex, int nonNullElementCount); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java index f73fd9e21560..d6d0e01babaf 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java @@ -7,19 +7,14 @@ import java.util.List; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; import org.hibernate.query.spi.QueryOptionsAdapter; -import org.hibernate.sql.ast.tree.expression.JdbcParameter; -import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterImpl; -import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import static org.hibernate.loader.ast.internal.LoaderHelper.loadByArrayParameter; @@ -51,14 +46,14 @@ public List loadEntitiesWithUnresolvedIds( MultiNaturalIdLoadOptions loadOptions, LockOptions lockOptions, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); - final JdbcMapping arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( + final var factory = session.getFactory(); + final var arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( getNaturalIdMapping().getSingleJdbcMapping(), keyClass, factory ); - final JdbcParameter jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); - final SelectStatement sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( + final var jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + final var sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( getLoadable(), getNaturalIdAttribute(), session.getLoadQueryInfluencers(), @@ -66,7 +61,7 @@ public List loadEntitiesWithUnresolvedIds( jdbcParameter, factory ); - final JdbcOperationQuerySelect jdbcSelectOperation = + final var jdbcSelectOperation = factory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() .buildSelectTranslator( factory, sqlAst ) .translate( JdbcParameterBindings.NO_BINDINGS, new QueryOptionsAdapter() { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderInPredicate.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderInPredicate.java index a517cf62fcc3..89e4bdb221b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderInPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderInPredicate.java @@ -36,13 +36,13 @@ private MultiNaturalIdLoadingBatcher getBatcher( MultiNaturalIdLoadOptions loadOptions, LockOptions lockOptions, SharedSessionContractImplementor session) { - final EntityMappingType descriptor = getEntityDescriptor(); + final var entityDescriptor = getEntityDescriptor(); return new MultiNaturalIdLoadingBatcher( - descriptor, - descriptor.getNaturalIdMapping(), + entityDescriptor, + entityDescriptor.getNaturalIdMapping(), Math.min( naturalIds.length, getMaxBatchSize( naturalIds, loadOptions, session ) ), // naturalId here is the one passed in by the API as part of the values array - (naturalId, s) -> descriptor.getNaturalIdMapping().normalizeInput( naturalId ), + (naturalId, s) -> entityDescriptor.getNaturalIdMapping().normalizeInput( naturalId ), session.getLoadQueryInfluencers(), lockOptions, session.getFactory() @@ -59,7 +59,8 @@ private int getMaxBatchSize( } else { return session.getJdbcServices().getJdbcEnvironment().getDialect() - .getMultiKeyLoadSizingStrategy().determineOptimalBatchLoadSize( + .getMultiKeyLoadSizingStrategy() + .determineOptimalBatchLoadSize( getEntityDescriptor().getNaturalIdMapping().getJdbcTypeCount(), naturalIds.length, session.getFactory().getSessionFactoryOptions().inClauseParameterPaddingEnabled() diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java index 75697020a27a..d9d723a73a18 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java @@ -12,11 +12,9 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SubselectFetch; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.query.spi.QueryOptionsAdapter; -import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; @@ -25,6 +23,8 @@ import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; +import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; + /** * Batch support for natural-id multi loading */ @@ -62,7 +62,7 @@ public MultiNaturalIdLoadingBatcher( LockOptions lockOptions, SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(); + final var jdbcParametersBuilder = JdbcParametersList.newBuilder(); sqlSelect = LoaderSelectBuilder.createSelect( entityDescriptor, @@ -81,21 +81,21 @@ public MultiNaturalIdLoadingBatcher( this.keyValueResolver = keyValueResolver; - final SqlAstTranslatorFactory sqlAstTranslatorFactory = - sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory(); - this.jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect ) - .translate( null, new QueryOptionsAdapter() { - @Override - public LockOptions getLockOptions() { - return lockOptions; - } - } ); + this.jdbcSelect = + sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() + .buildSelectTranslator( sessionFactory, sqlSelect ) + .translate( null, new QueryOptionsAdapter() { + @Override + public LockOptions getLockOptions() { + return lockOptions; + } + } ); this.lockOptions = lockOptions; } public List multiLoad(Object[] naturalIdValues, SharedSessionContractImplementor session) { - final ArrayList multiLoadResults = CollectionHelper.arrayList( naturalIdValues.length ); - final JdbcParameterBindingsImpl jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); + final ArrayList multiLoadResults = arrayList( naturalIdValues.length ); + final var jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() ); int offset = 0; int size = 0; @@ -115,8 +115,7 @@ public List multiLoad(Object[] naturalIdValues, SharedSessionContractImpl if ( offset == jdbcParameters.size() ) { // we've hit the batch mark - final List batchResults = performLoad( jdbcParamBindings, session, size ); - multiLoadResults.addAll( batchResults ); + multiLoadResults.addAll( performLoad( jdbcParamBindings, session, size ) ); jdbcParamBindings.clear(); offset = 0; size = 0; @@ -135,8 +134,7 @@ public List multiLoad(Object[] naturalIdValues, SharedSessionContractImpl ); size++; } - final List batchResults = performLoad( jdbcParamBindings, session, size ); - multiLoadResults.addAll( batchResults ); + multiLoadResults.addAll( performLoad( jdbcParamBindings, session, size ) ); } return multiLoadResults; @@ -146,23 +144,16 @@ private List performLoad( JdbcParameterBindings jdbcParamBindings, SharedSessionContractImplementor session, int size) { - final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler; - - if ( session.getLoadQueryInfluencers().hasSubselectLoadableCollections( entityDescriptor.getEntityPersister() ) ) { - subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler( - session.getPersistenceContext().getBatchFetchQueue(), - sqlSelect, - jdbcParameters, - jdbcParamBindings - ); - - - } - else { - subSelectFetchableKeysHandler = null; - } - - + final var subSelectFetchableKeysHandler = + session.getLoadQueryInfluencers() + .hasSubselectLoadableCollections( entityDescriptor.getEntityPersister() ) + ? SubselectFetch.createRegistrationHandler( + session.getPersistenceContext().getBatchFetchQueue(), + sqlSelect, + jdbcParameters, + jdbcParamBindings + ) + : null; return session.getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParamBindings, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SimpleNaturalIdLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SimpleNaturalIdLoader.java index c495c0bd463a..8ae505495954 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SimpleNaturalIdLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SimpleNaturalIdLoader.java @@ -9,7 +9,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JdbcParameter; @@ -43,7 +42,7 @@ protected void applyNaturalIdRestriction( LoaderSqlAstCreationState sqlAstCreationState, SharedSessionContractImplementor session) { final var expressionResolver = sqlAstCreationState.getSqlExpressionResolver(); - final SingularAttributeMapping naturalIdMapping = naturalIdMapping().getAttribute(); + final var naturalIdMapping = naturalIdMapping().getAttribute(); if ( bindValue == null ) { naturalIdMapping.forEachSelectable( (index, selectable) -> { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java index da724ee9351e..1f65168f7587 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderProvidedQueryImpl.java @@ -10,7 +10,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.query.QueryFlushMode; import org.hibernate.query.named.NamedQueryMemento; -import org.hibernate.query.spi.QueryImplementor; import jakarta.persistence.Parameter; import org.hibernate.type.descriptor.java.JavaType; @@ -41,8 +40,8 @@ public EntityMappingType getLoadable() { @Override @SuppressWarnings("unchecked") public T load(Object pkValue, LockOptions lockOptions, Boolean readOnly, SharedSessionContractImplementor session) { - final JavaType mappedJavaType = (JavaType) entityDescriptor.getMappedJavaType(); - final QueryImplementor query = namedQueryMemento.toQuery( session, mappedJavaType.getJavaTypeClass() ); + final var mappedJavaType = (JavaType) entityDescriptor.getMappedJavaType(); + final var query = namedQueryMemento.toQuery( session, mappedJavaType.getJavaTypeClass() ); query.setParameter( (Parameter) query.getParameters().iterator().next(), pkValue ); query.setQueryFlushMode( QueryFlushMode.NO_FLUSH ); return query.uniqueResult(); 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 6c3642e3c9ee..dd27177aeeb9 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 @@ -15,7 +15,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.ast.spi.CascadingFetchProfile; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.spi.JdbcParametersList; /** @@ -53,10 +52,10 @@ protected SingleIdEntityLoaderStandardImpl( this.loadPlanCreator = loadPlanCreator; // see org.hibernate.persister.entity.AbstractEntityPersister#createLoaders // we should preload a few - maybe LockMode.NONE and LockMode.READ - final LockOptions noLocking = new LockOptions(); - final SingleIdLoadPlan plan = loadPlanCreator.apply( noLocking, influencers ); + final var noLocking = new LockOptions(); + final var singleIdLoadPlan = loadPlanCreator.apply( noLocking, influencers ); if ( isLoadPlanReusable( noLocking, influencers ) ) { - selectByLockMode.put( LockMode.NONE, plan ); + selectByLockMode.put( LockMode.NONE, singleIdLoadPlan ); } } @@ -99,14 +98,14 @@ else if ( influencers.hasEnabledCascadingFetchProfile() private SingleIdLoadPlan getRegularLoadPlan(LockOptions lockOptions, LoadQueryInfluencers influencers) { if ( isLoadPlanReusable( lockOptions, influencers ) ) { - final SingleIdLoadPlan existing = selectByLockMode.get( lockOptions.getLockMode() ); + final var existing = selectByLockMode.get( lockOptions.getLockMode() ); if ( existing != null ) { return existing; } else { - final SingleIdLoadPlan plan = loadPlanCreator.apply( lockOptions, influencers ); - selectByLockMode.put( lockOptions.getLockMode(), plan ); - return plan; + final var singleIdLoadPlan = loadPlanCreator.apply( lockOptions, influencers ); + selectByLockMode.put( lockOptions.getLockMode(), singleIdLoadPlan ); + return singleIdLoadPlan; } } else { @@ -115,19 +114,17 @@ private SingleIdLoadPlan getRegularLoadPlan(LockOptions lockOptions, LoadQuer } private SingleIdLoadPlan getInternalCascadeLoadPlan(LockOptions lockOptions, LoadQueryInfluencers influencers) { - final CascadingFetchProfile fetchProfile = - influencers.getEnabledCascadingFetchProfile(); + final var fetchProfile = influencers.getEnabledCascadingFetchProfile(); if ( selectByInternalCascadeProfile == null ) { selectByInternalCascadeProfile = new EnumMap<>( CascadingFetchProfile.class ); } else { - final SingleIdLoadPlan existing = - selectByInternalCascadeProfile.get( fetchProfile ); + final var existing = selectByInternalCascadeProfile.get( fetchProfile ); if ( existing != null ) { return existing; } } - final SingleIdLoadPlan plan = loadPlanCreator.apply( lockOptions, influencers ); + final var plan = loadPlanCreator.apply( lockOptions, influencers ); selectByInternalCascadeProfile.put( fetchProfile, plan ); return plan; } @@ -136,8 +133,10 @@ private boolean isLoadPlanReusable(LockOptions lockOptions, LoadQueryInfluencers if ( lockOptions.getLockMode().isPessimistic() && lockOptions.hasNonDefaultOptions() ) { return false; } - return !getLoadable().isAffectedByEntityGraph( influencers ) - && !getLoadable().isAffectedByEnabledFetchProfiles( influencers ); + else { + return !getLoadable().isAffectedByEntityGraph( influencers ) + && !getLoadable().isAffectedByEnabledFetchProfiles( influencers ); + } } private static SingleIdLoadPlan createLoadPlan( @@ -146,23 +145,22 @@ private static SingleIdLoadPlan createLoadPlan( LoadQueryInfluencers influencers, SessionFactoryImplementor factory) { - final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(); - final SelectStatement sqlAst = LoaderSelectBuilder.createSelect( - loadable, - // null here means to select everything - null, - loadable.getIdentifierMapping(), - null, - 1, - influencers, - lockOptions, - jdbcParametersBuilder::add, - factory - ); + final var jdbcParametersBuilder = JdbcParametersList.newBuilder(); return new SingleIdLoadPlan<>( loadable, loadable.getIdentifierMapping(), - sqlAst, + LoaderSelectBuilder.createSelect( + loadable, + // null here means to select everything + null, + loadable.getIdentifierMapping(), + null, + 1, + influencers, + lockOptions, + jdbcParametersBuilder::add, + factory + ), jdbcParametersBuilder.build(), lockOptions, factory diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java index e9e3b99f59a7..d025073601d0 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java @@ -21,7 +21,6 @@ import org.hibernate.sql.exec.internal.CallbackImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.spi.Callback; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.exec.spi.JdbcSelect; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; @@ -124,7 +123,7 @@ public T load( final int jdbcTypeCount = restrictivePart.getJdbcTypeCount(); assert jdbcParameters.size() % jdbcTypeCount == 0; - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount ); + final var jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount ); int offset = 0; while ( offset < jdbcParameters.size() ) { @@ -137,7 +136,7 @@ public T load( ); } assert offset == jdbcParameters.size(); - final QueryOptions queryOptions = new SimpleQueryOptions( lockOptions, readOnly ); + final var queryOptions = new SimpleQueryOptions( lockOptions, readOnly ); final Callback callback = new CallbackImpl(); final List list = session.getJdbcServices().getJdbcSelectExecutor().list( @@ -162,10 +161,11 @@ public T load( if ( list.isEmpty() ) { return null; } - - final T entity = list.get( 0 ); - callback.invokeAfterLoadActions( entity, entityMappingType, session ); - return entity; + else { + final T entity = list.get( 0 ); + callback.invokeAfterLoadActions( entity, entityMappingType, session ); + return entity; + } } private static class SingleIdExecutionContext extends BaseExecutionContext { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleUniqueKeyEntityLoaderStandard.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleUniqueKeyEntityLoaderStandard.java index 0d769f8a811b..166709179f7e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleUniqueKeyEntityLoaderStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleUniqueKeyEntityLoaderStandard.java @@ -14,7 +14,6 @@ import org.hibernate.loader.ast.spi.SingleUniqueKeyEntityLoader; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.EmbeddableMappingType; -import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.ManagedMappingType; import org.hibernate.metamodel.mapping.ModelPart; @@ -57,9 +56,9 @@ public SingleUniqueKeyEntityLoaderStandard( ? toOneAttributeMapping.getForeignKeyDescriptor() : uniqueKeyMapping; - final SessionFactoryImplementor factory = entityDescriptor.getEntityPersister().getFactory(); - final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder(); - final SelectStatement sqlAst = LoaderSelectBuilder.createSelectByUniqueKey( + final var factory = entityDescriptor.getEntityPersister().getFactory(); + final var builder = JdbcParametersList.newBuilder(); + final var sqlAst = LoaderSelectBuilder.createSelectByUniqueKey( entityDescriptor, emptyList(), uniqueKeyMapping, @@ -75,13 +74,12 @@ public SingleUniqueKeyEntityLoaderStandard( private static String getAttributePath(AttributeMapping attribute) { ManagedMappingType declaringType = attribute.getDeclaringType(); - if ( declaringType instanceof EmbeddableMappingType ) { - final StringBuilder path = new StringBuilder(); + if ( declaringType instanceof EmbeddableMappingType embeddableMappingType ) { + final var path = new StringBuilder(); path.append( attribute.getAttributeName() ); do { - final EmbeddableValuedModelPart embeddedValueMapping = - ( (EmbeddableMappingType) declaringType ).getEmbeddedValueMapping(); - attribute = embeddedValueMapping.asAttributeMapping(); + final var valueMapping = embeddableMappingType.getEmbeddedValueMapping(); + attribute = valueMapping.asAttributeMapping(); if ( attribute == null ) { break; } @@ -105,7 +103,7 @@ public T load( LockOptions lockOptions, Boolean readOnly, SharedSessionContractImplementor session) { - final JdbcParameterBindings bindings = jdbcParameterBindings( ukValue, jdbcParameters, session ); + final var bindings = jdbcParameterBindings( ukValue, jdbcParameters, session ); final List list = list( jdbcSelect, bindings, new SingleUKEntityLoaderExecutionContext( uniqueKeyAttributePath, ukValue, session, readOnly ) ); return switch ( list.size() ) { @@ -118,10 +116,10 @@ public T load( @Override public Object resolveId(Object ukValue, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); + final var factory = session.getFactory(); // todo (6.0) : cache the SQL AST and JdbcParameters - final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder(); - final SelectStatement sqlAst = LoaderSelectBuilder.createSelectByUniqueKey( + final var builder = JdbcParametersList.newBuilder(); + final var sqlAst = LoaderSelectBuilder.createSelectByUniqueKey( entityDescriptor, singletonList( entityDescriptor.getIdentifierMapping() ), uniqueKeyAttribute, @@ -131,8 +129,8 @@ public Object resolveId(Object ukValue, SharedSessionContractImplementor session builder::add, factory ); - final JdbcParameterBindings bindings = jdbcParameterBindings( ukValue, builder.build(), session ); - final JdbcOperationQuerySelect jdbcSelect = getJdbcSelect( factory, sqlAst, bindings ); + final var bindings = jdbcParameterBindings( ukValue, builder.build(), session ); + final var jdbcSelect = getJdbcSelect( factory, sqlAst, bindings ); final List list = list( jdbcSelect, bindings, new NoCallbackExecutionContext( session ) ); assert list.size() == 1; return list.get( 0 ); @@ -142,7 +140,7 @@ private JdbcParameterBindings jdbcParameterBindings( Object ukValue, JdbcParametersList parameters, SharedSessionContractImplementor session) { - final JdbcParameterBindings bindings = new JdbcParameterBindingsImpl( parameters.size() ); + final var bindings = new JdbcParameterBindingsImpl( parameters.size() ); final int offset = bindings.registerParametersForEachJdbcValue( ukValue, uniqueKeyAttribute, parameters, session ); assert offset == parameters.size(); return bindings; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/StandardBatchLoaderFactory.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/StandardBatchLoaderFactory.java index d6a2225f804b..200f33846457 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/StandardBatchLoaderFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/StandardBatchLoaderFactory.java @@ -15,7 +15,6 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.type.BasicType; -import org.hibernate.type.Type; import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.supportsSqlArrayType; @@ -34,9 +33,9 @@ public EntityBatchLoader createEntityBatchLoader( int domainBatchSize, EntityMappingType entityDescriptor, LoadQueryInfluencers influencers) { - final SessionFactoryImplementor factory = influencers.getSessionFactory(); - // NOTE : don't use the EntityIdentifierMapping here because it will not be known until later - final Type identifierType = entityDescriptor.getEntityPersister().getIdentifierType(); + final var factory = influencers.getSessionFactory(); + // NOTE: don't use the EntityIdentifierMapping here because it will not be known until later + final var identifierType = entityDescriptor.getEntityPersister().getIdentifierType(); if ( identifierType.getColumnSpan( factory.getRuntimeMetamodels() ) == 1 && supportsSqlArrayType( factory.getJdbcServices().getDialect() ) && identifierType instanceof BasicType ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableHelper.java index e3d55aa42bf3..dbb05cd63ee6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableHelper.java @@ -4,14 +4,14 @@ */ package org.hibernate.metamodel.internal; -import java.util.Arrays; +import static java.util.Arrays.binarySearch; public class EmbeddableHelper { public static int[] determineMappingIndex(String[] sortedNames, String[] names) { final int[] index = new int[sortedNames.length]; int i = 0; for ( String name : names ) { - final int mappingIndex = Arrays.binarySearch( sortedNames, name ); + final int mappingIndex = binarySearch( sortedNames, name ); if ( mappingIndex != -1 ) { index[i++] = mappingIndex; } @@ -22,7 +22,7 @@ public static int[] determineMappingIndex(String[] sortedNames, String[] names) public static boolean resolveIndex(String[] sortedComponentNames, String[] componentNames, int[] index) { boolean hasGaps = false; for ( int i = 0; i < componentNames.length; i++ ) { - final int newIndex = Arrays.binarySearch( sortedComponentNames, componentNames[i] ); + final int newIndex = binarySearch( sortedComponentNames, componentNames[i] ); index[i] = newIndex; hasGaps = hasGaps || newIndex < 0; } diff --git a/hibernate-core/src/main/java/org/hibernate/resource/jdbc/spi/StatementInspector.java b/hibernate-core/src/main/java/org/hibernate/resource/jdbc/spi/StatementInspector.java index d833e00d176a..4d8c7eb8b788 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/jdbc/spi/StatementInspector.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/jdbc/spi/StatementInspector.java @@ -5,6 +5,8 @@ package org.hibernate.resource.jdbc.spi; +import org.hibernate.engine.creation.spi.SessionBuilderImplementor; + import java.io.Serializable; /** @@ -14,19 +16,19 @@ *
    *
  • shared by all sessions created by a given session factory, in * which case it must be thread-safe, or - *
  • a dedicated instance {@linkplain - * org.hibernate.SessionBuilder#statementInspector registered} + *
  • a dedicated instance + * {@linkplain SessionBuilderImplementor#statementInspector(StatementInspector) registered} * for a certain session. *
*

* An implementation may be specified via the configuration property - * {@value org.hibernate.cfg.AvailableSettings#STATEMENT_INSPECTOR}. + * {@value org.hibernate.cfg.JdbcSettings#STATEMENT_INSPECTOR}. * An implementation registered this way is shared between sessions. * - * @see org.hibernate.cfg.AvailableSettings#STATEMENT_INSPECTOR + * @see org.hibernate.cfg.JdbcSettings#STATEMENT_INSPECTOR * @see org.hibernate.cfg.Configuration#setStatementInspector(StatementInspector) * @see org.hibernate.boot.SessionFactoryBuilder#applyStatementInspector(StatementInspector) - * @see org.hibernate.SessionBuilder#statementInspector(StatementInspector) + * @see SessionBuilderImplementor#statementInspector(StatementInspector) * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingImpl.java index ce88d3c147f9..4c3a45f6fb5d 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingImpl.java @@ -4,7 +4,6 @@ */ package org.hibernate.sql.exec.internal; -import java.util.Locale; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.sql.exec.spi.JdbcParameterBinding; @@ -17,9 +16,9 @@ public class JdbcParameterBindingImpl implements JdbcParameterBinding { private final Object bindValue; public JdbcParameterBindingImpl(JdbcMapping jdbcMapping, Object bindValue) { - assert bindValue == null || jdbcMapping == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue ) - : String.format( Locale.ROOT, "Unexpected value type (expected : %s) : %s (%s)", - jdbcMapping.getJdbcJavaType().getJavaTypeClass().getName(), bindValue, bindValue.getClass().getName() ); +// assert bindValue == null || jdbcMapping == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue ) +// : String.format( Locale.ROOT, "Unexpected value type (expected : %s) : %s (%s)", +// jdbcMapping.getJdbcJavaType().getJavaTypeClass().getName(), bindValue, bindValue.getClass().getName() ); this.jdbcMapping = jdbcMapping; this.bindValue = bindValue;