Skip to content

Commit

Permalink
further cleanups on multi id loaders
Browse files Browse the repository at this point in the history
Signed-off-by: Gavin King <[email protected]>
  • Loading branch information
gavinking committed Oct 26, 2024
1 parent 61fa700 commit 875b99c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@

import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.LoadEvent;
import org.hibernate.event.spi.LoadEventListener;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.ast.spi.MultiIdEntityLoader;
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
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;

import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
import static org.hibernate.loader.ast.internal.CacheEntityLoaderHelper.loadFromSessionCacheStatic;
import static org.hibernate.loader.ast.internal.LoaderHelper.getReadOnlyFromLoadQueryInfluencers;
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER;

/**
* Base support for {@link MultiIdEntityLoader} implementations.
Expand Down Expand Up @@ -51,6 +56,18 @@ public EntityIdentifierMapping getIdentifierMapping() {
return identifierMapping;
}

protected JdbcServices getJdbcServices() {
return getSessionFactory().getJdbcServices();
}

protected SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory();
}

protected JdbcSelectExecutor getJdbcSelectExecutor() {
return getJdbcServices().getJdbcSelectExecutor();
}

@Override
public EntityMappingType getLoadable() {
return getEntityDescriptor();
Expand All @@ -71,9 +88,8 @@ protected List<T> performOrderedMultiLoad(
Object[] ids,
MultiIdLoadOptions loadOptions,
EventSource session) {
if ( MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) {
MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER.tracef( "#performOrderedMultiLoad(`%s`, ..)",
getLoadable().getEntityName() );
if ( MULTI_KEY_LOAD_LOGGER.isTraceEnabled() ) {
MULTI_KEY_LOAD_LOGGER.tracef( "#performOrderedMultiLoad(`%s`, ..)", getLoadable().getEntityName() );
}

assert loadOptions.isOrderReturnEnabled();
Expand All @@ -87,7 +103,7 @@ protected List<T> performOrderedMultiLoad(

final int maxBatchSize = maxBatchSize( ids, loadOptions );

final List<Object> result = CollectionHelper.arrayList( ids.length );
final List<Object> result = arrayList( ids.length );

final List<Object> idsInBatch = new ArrayList<>();
final List<Integer> elementPositionsLoadedByBatch = new ArrayList<>();
Expand Down Expand Up @@ -146,7 +162,7 @@ protected boolean loadFromCaches(
getLoadable().getJavaType().getJavaTypeClass().getName(),
lockOptions,
session,
LoaderHelper.getReadOnlyFromLoadQueryInfluencers( session )
getReadOnlyFromLoadQueryInfluencers( session )
);

Object managedEntity = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@

import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.engine.internal.BatchFetchQueueHelper;
import org.hibernate.engine.spi.BatchFetchQueue;
import org.hibernate.engine.jdbc.spi.JdbcServices;
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.SubselectFetch;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.LoadEvent;
import org.hibernate.event.spi.LoadEventListener;
Expand All @@ -28,6 +26,7 @@
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
Expand All @@ -36,29 +35,37 @@
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.exec.spi.JdbcSelectExecutor;
import org.hibernate.sql.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ManagedResultConsumer;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.hibernate.type.descriptor.java.JavaType;

import static java.lang.Boolean.TRUE;
import static org.hibernate.engine.internal.BatchFetchQueueHelper.removeBatchLoadableEntityKey;
import static org.hibernate.engine.spi.SubselectFetch.createRegistrationHandler;
import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
import static org.hibernate.loader.ast.internal.CacheEntityLoaderHelper.loadFromSessionCacheStatic;
import static org.hibernate.loader.ast.internal.LoaderHelper.getReadOnlyFromLoadQueryInfluencers;
import static org.hibernate.loader.ast.internal.LoaderHelper.loadByArrayParameter;
import static org.hibernate.loader.ast.internal.LoaderSelectBuilder.createSelectBySingleArrayParameter;
import static org.hibernate.loader.ast.internal.MultiKeyLoadHelper.resolveArrayJdbcMapping;
import static org.hibernate.sql.exec.spi.JdbcParameterBindings.NO_BINDINGS;

/**
* @author Steve Ebersole
*/
public class MultiIdEntityLoaderArrayParam<E> extends AbstractMultiIdEntityLoader<E> implements SqlArrayMultiKeyLoader {
private final JdbcMapping arrayJdbcMapping;
private final JdbcParameter jdbcParameter;
private final int idJdbcTypeCount;

public MultiIdEntityLoaderArrayParam(EntityMappingType entityDescriptor, int identifierColumnSpan, SessionFactoryImplementor sessionFactory) {
public MultiIdEntityLoaderArrayParam(
EntityMappingType entityDescriptor,
SessionFactoryImplementor sessionFactory) {
super( entityDescriptor, sessionFactory );
this.idJdbcTypeCount = identifierColumnSpan;
final Class<?> arrayClass = createTypedArray( 0 ).getClass();
arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping(
arrayJdbcMapping = resolveArrayJdbcMapping(
getSessionFactory().getTypeConfiguration().getBasicTypeRegistry().getRegisteredType( arrayClass ),
getIdentifierMapping().getJdbcMapping(),
arrayClass,
Expand All @@ -83,7 +90,7 @@ protected void handleResults(
// the element value at this position in the result List should be
// the EntityKey for that entity - reuse it
final EntityKey entityKey = (EntityKey) result.get( position );
BatchFetchQueueHelper.removeBatchLoadableEntityKey( entityKey, session );
removeBatchLoadableEntityKey( entityKey, session );
Object entity = persistenceContext.getEntity( entityKey );
if ( entity != null && !loadOptions.isReturnOfDeletedEntitiesEnabled() ) {
// make sure it is not DELETED
Expand All @@ -102,71 +109,52 @@ protected void handleResults(

@Override
protected int maxBatchSize(Object[] ids, MultiIdLoadOptions loadOptions) {
if ( loadOptions.getBatchSize() != null && loadOptions.getBatchSize() > 0 ) {
return loadOptions.getBatchSize();
}
else {
// disable batching by default
return ids.length;
// return getSessionFactory().getJdbcServices().getJdbcEnvironment().getDialect()
// .getBatchLoadSizingStrategy().determineOptimalBatchLoadSize(
// idJdbcTypeCount,
// ids.length,
// getSessionFactory().getSessionFactoryOptions().inClauseParameterPaddingEnabled()
// );
}
final Integer explicitBatchSize = loadOptions.getBatchSize();
return explicitBatchSize != null && explicitBatchSize > 0
? explicitBatchSize
// disable batching by default
: ids.length;
}

@Override
protected void loadEntitiesById(
List<Object> idsToLoadFromDatabase,
List<Object> idsInBatch,
LockOptions lockOptions,
MultiIdLoadOptions loadOptions,
EventSource session) {
final SelectStatement sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter(
final SelectStatement sqlAst = createSelectBySingleArrayParameter(
getLoadable(),
getIdentifierMapping(),
session.getLoadQueryInfluencers(),
lockOptions,
jdbcParameter,
getSessionFactory()
);
final JdbcOperationQuerySelect jdbcSelectOperation = getSessionFactory().getJdbcServices()
.getJdbcEnvironment()
.getSqlAstTranslatorFactory()
.buildSelectTranslator( getSessionFactory(), sqlAst )
.translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE );

final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(1);
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( arrayJdbcMapping, idsToLoadFromDatabase.toArray( createTypedArray(0 ) ) )
);

final PersistenceContext persistenceContext = session.getPersistenceContext();
final BatchFetchQueue batchFetchQueue = persistenceContext.getBatchFetchQueue();
jdbcParameterBindings.addBinding( jdbcParameter,
new JdbcParameterBindingImpl( arrayJdbcMapping, idsInBatch.toArray( createTypedArray(0) ) ) );

final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler(
batchFetchQueue,
sqlAst,
JdbcParametersList.singleton( jdbcParameter ),
jdbcParameterBindings
);

session.getJdbcServices().getJdbcSelectExecutor().executeQuery(
jdbcSelectOperation,
getJdbcSelectExecutor().executeQuery(
getSqlAstTranslatorFactory().buildSelectTranslator( getSessionFactory(), sqlAst )
.translate( NO_BINDINGS, QueryOptions.NONE ),
jdbcParameterBindings,
new ExecutionContextWithSubselectFetchHandler( session,
subSelectFetchableKeysHandler,
new ExecutionContextWithSubselectFetchHandler(
session,
createRegistrationHandler(
session.getPersistenceContext().getBatchFetchQueue(),
sqlAst,
JdbcParametersList.singleton( jdbcParameter ),
jdbcParameterBindings
),
TRUE.equals( loadOptions.getReadOnly( session ) ) ),
RowTransformerStandardImpl.instance(),
null,
idsToLoadFromDatabase.size(),
idsInBatch.size(),
ManagedResultConsumer.INSTANCE
);
}


@Override
protected <K> List<E> performUnorderedMultiLoad(
K[] ids,
Expand All @@ -180,7 +168,7 @@ protected <K> List<E> performUnorderedMultiLoad(
}

final List<E> result = CollectionHelper.arrayList( ids.length );
final LockOptions lockOptions = (loadOptions.getLockOptions() == null)
final LockOptions lockOptions = loadOptions.getLockOptions() == null
? new LockOptions( LockMode.NONE )
: loadOptions.getLockOptions();

Expand All @@ -198,21 +186,19 @@ protected <K> List<E> performUnorderedMultiLoad(
return result;
}

final SelectStatement sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter(
final SelectStatement sqlAst = createSelectBySingleArrayParameter(
getLoadable(),
getIdentifierMapping(),
session.getLoadQueryInfluencers(),
lockOptions,
jdbcParameter,
getSessionFactory()
);
final JdbcOperationQuerySelect jdbcSelectOperation = getSessionFactory().getJdbcServices()
.getJdbcEnvironment()
.getSqlAstTranslatorFactory()
.buildSelectTranslator( getSessionFactory(), sqlAst )
.translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE );
final JdbcOperationQuerySelect jdbcSelectOperation =
getSqlAstTranslatorFactory().buildSelectTranslator( getSessionFactory(), sqlAst )
.translate( NO_BINDINGS, QueryOptions.NONE );

final List<E> databaseResults = LoaderHelper.loadByArrayParameter(
final List<E> databaseResults = loadByArrayParameter(
idsToLoadFromDatabase,
sqlAst,
jdbcSelectOperation,
Expand All @@ -236,7 +222,7 @@ protected <K> List<E> performUnorderedMultiLoad(
continue;
}
// found or not, remove the key from the batch-fetch queue
BatchFetchQueueHelper.removeBatchLoadableEntityKey( id, getLoadable(), session );
removeBatchLoadableEntityKey( id, getLoadable(), session );
}

return result;
Expand Down Expand Up @@ -272,7 +258,7 @@ protected final <R,K> K[] processResolvableEntities(
getLoadable().getJavaType().getJavaTypeClass().getName(),
lockOptions,
session,
LoaderHelper.getReadOnlyFromLoadQueryInfluencers( session )
getReadOnlyFromLoadQueryInfluencers( session )
);

Object managedEntity = null;
Expand Down
Loading

0 comments on commit 875b99c

Please sign in to comment.