HHH-16679 Avoid type pollution problems on iterations of List<JdbcParameter>

This commit is contained in:
Sanne Grinovero 2023-05-20 21:29:38 +01:00 committed by Sanne Grinovero
parent 896c1ea8b5
commit ec573202ad
27 changed files with 387 additions and 90 deletions

View File

@ -18,6 +18,7 @@ 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.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
@ -30,14 +31,14 @@ import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer;
public class SubselectFetch {
private final QuerySpec loadingSqlAst;
private final TableGroup ownerTableGroup;
private final List<JdbcParameter> loadingJdbcParameters;
private final JdbcParametersList loadingJdbcParameters;
private final JdbcParameterBindings loadingJdbcParameterBindings;
private final Set<EntityKey> resultingEntityKeys;
public SubselectFetch(
QuerySpec loadingSqlAst,
TableGroup ownerTableGroup,
List<JdbcParameter> loadingJdbcParameters,
JdbcParametersList loadingJdbcParameters,
JdbcParameterBindings loadingJdbcParameterBindings,
Set<EntityKey> resultingEntityKeys) {
this.loadingSqlAst = loadingSqlAst;
@ -47,7 +48,7 @@ public class SubselectFetch {
this.resultingEntityKeys = resultingEntityKeys;
}
public List<JdbcParameter> getLoadingJdbcParameters() {
public JdbcParametersList getLoadingJdbcParameters() {
// todo (6.0) : do not believe this is needed
// - see org.hibernate.loader.ast.internal.LoaderSelectBuilder.generateSelect(org.hibernate.engine.spi.SubselectFetch)
return loadingJdbcParameters;
@ -93,7 +94,7 @@ public class SubselectFetch {
BatchFetchQueue batchFetchQueue,
SelectStatement sqlAst,
TableGroup tableGroup,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
JdbcParameterBindings jdbcParameterBindings) {
return new StandardRegistrationHandler(
@ -108,7 +109,7 @@ public class SubselectFetch {
public static RegistrationHandler createRegistrationHandler(
BatchFetchQueue batchFetchQueue,
SelectStatement sqlAst,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
JdbcParameterBindings jdbcParameterBindings) {
final List<TableGroup> roots = sqlAst.getQuerySpec().getFromClause().getRoots();
if ( roots.isEmpty() ) {
@ -132,7 +133,7 @@ public class SubselectFetch {
public static class StandardRegistrationHandler implements RegistrationHandler {
private final BatchFetchQueue batchFetchQueue;
private final SelectStatement loadingSqlAst;
private final List<JdbcParameter> loadingJdbcParameters;
private final JdbcParametersList loadingJdbcParameters;
private final JdbcParameterBindings loadingJdbcParameterBindings;
private final Map<NavigablePath, SubselectFetch> subselectFetches = new HashMap<>();
@ -140,7 +141,7 @@ public class SubselectFetch {
BatchFetchQueue batchFetchQueue,
SelectStatement loadingSqlAst,
TableGroup ownerTableGroup,
List<JdbcParameter> loadingJdbcParameters,
JdbcParametersList loadingJdbcParameters,
JdbcParameterBindings loadingJdbcParameterBindings) {
this.batchFetchQueue = batchFetchQueue;
this.loadingSqlAst = loadingSqlAst;

View File

@ -49,6 +49,7 @@ import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.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.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
@ -297,7 +298,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
public Object resolveIdToNaturalId(Object id, SharedSessionContractImplementor session) {
final SessionFactoryImplementor sessionFactory = session.getFactory();
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
final SelectStatement sqlSelect = LoaderSelectBuilder.createSelect(
entityDescriptor(),
Collections.singletonList( naturalIdMapping() ),
@ -306,10 +307,12 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
1,
session.getLoadQueryInfluencers(),
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
final JdbcParametersList jdbcParameters = jdbcParametersBuilder.build();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();

View File

@ -7,7 +7,6 @@
package org.hibernate.loader.ast.internal;
import java.lang.reflect.Array;
import java.util.Collections;
import org.hibernate.LockOptions;
import org.hibernate.collection.spi.PersistentCollection;
@ -29,6 +28,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.type.BasicType;
@ -138,7 +138,7 @@ public class CollectionBatchLoaderArrayParam
final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler(
session.getPersistenceContext().getBatchFetchQueue(),
sqlSelect,
Collections.singletonList( jdbcParameter ),
JdbcParametersList.singleton( jdbcParameter ),
jdbcParameterBindings
);

View File

@ -27,6 +27,7 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.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_DEBUG_ENABLED;
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER;
@ -41,7 +42,7 @@ public class CollectionBatchLoaderInPredicate
implements CollectionBatchLoader, SqlArrayMultiKeyLoader {
private final int keyColumnCount;
private final int sqlBatchSize;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
private final SelectStatement sqlAst;
private final JdbcOperationQuerySelect jdbcSelect;
@ -68,7 +69,7 @@ public class CollectionBatchLoaderInPredicate
);
}
this.jdbcParameters = new ArrayList<>();
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
this.sqlAst = LoaderSelectBuilder.createSelect(
attributeMapping,
null,
@ -77,9 +78,10 @@ public class CollectionBatchLoaderInPredicate
sqlBatchSize,
influencers,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
this.jdbcParameters = jdbcParametersBuilder.build();
assert this.jdbcParameters.size() == this.sqlBatchSize * this.keyColumnCount;
this.jdbcSelect = sessionFactory.getJdbcServices()

View File

@ -24,12 +24,12 @@ 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.expression.JdbcParameter;
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.spi.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;
@ -39,7 +39,7 @@ import org.hibernate.sql.results.spi.ListResultsConsumer;
public class CollectionElementLoaderByIndex implements Loader {
private final PluralAttributeMapping attributeMapping;
private final SelectStatement sqlAst;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
private final int baseIndex;
private final int keyJdbcCount;
@ -88,7 +88,7 @@ public class CollectionElementLoaderByIndex implements Loader {
List<ModelPart> partsToSelect = new ArrayList<>();
partsToSelect.add( attributeMapping.getElementDescriptor() );
this.jdbcParameters = new ArrayList<>( keyJdbcCount );
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder( keyJdbcCount );
this.sqlAst = LoaderSelectBuilder.createSelect(
attributeMapping,
partsToSelect,
@ -97,9 +97,10 @@ public class CollectionElementLoaderByIndex implements Loader {
1,
influencers,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
this.jdbcParameters = jdbcParametersBuilder.build();
}
@Override
@ -115,7 +116,7 @@ public class CollectionElementLoaderByIndex implements Loader {
return sqlAst;
}
public List<JdbcParameter> getJdbcParameters() {
public JdbcParametersList getJdbcParameters() {
return jdbcParameters;
}

View File

@ -6,9 +6,6 @@
*/
package org.hibernate.loader.ast.internal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.LockOptions;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
@ -23,12 +20,12 @@ 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.expression.JdbcParameter;
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.spi.JdbcOperationQuerySelect;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
import org.hibernate.sql.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -44,7 +41,7 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
private final int keyJdbcCount;
private final SelectStatement sqlAst;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
public CollectionLoaderSingleKey(
PluralAttributeMapping attributeMapping,
@ -53,8 +50,8 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
this.attributeMapping = attributeMapping;
this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount();
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
this.jdbcParameters = new ArrayList<>();
this.sqlAst = LoaderSelectBuilder.createSelect(
attributeMapping,
null,
@ -63,9 +60,10 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
1,
influencers,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
this.jdbcParameters = jdbcParametersBuilder.build();
}
@Override
@ -81,7 +79,7 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
return sqlAst;
}
public List<JdbcParameter> getJdbcParameters() {
public JdbcParametersList getJdbcParameters() {
return jdbcParameters;
}

View File

@ -37,6 +37,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
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.results.graph.DomainResult;
import org.hibernate.sql.results.graph.internal.ImmutableFetchList;
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
@ -55,16 +56,14 @@ class DatabaseSnapshotExecutor {
private final EntityMappingType entityDescriptor;
private final JdbcOperationQuerySelect jdbcSelect;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
DatabaseSnapshotExecutor(
EntityMappingType entityDescriptor,
SessionFactoryImplementor sessionFactory) {
this.entityDescriptor = entityDescriptor;
this.jdbcParameters = new ArrayList<>(
entityDescriptor.getIdentifierMapping().getJdbcTypeCount()
);
JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder(
entityDescriptor.getIdentifierMapping().getJdbcTypeCount() );
final QuerySpec rootQuerySpec = new QuerySpec( true );
final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager();
@ -114,7 +113,7 @@ class DatabaseSnapshotExecutor {
);
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
jdbcParameters.add( jdbcParameter );
jdbcParametersBuilder.add( jdbcParameter );
final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver
.resolveSqlExpression( tableReference, selection );
@ -128,6 +127,7 @@ class DatabaseSnapshotExecutor {
);
}
);
this.jdbcParameters = jdbcParametersBuilder.build();
entityDescriptor.forEachAttributeMapping(

View File

@ -23,11 +23,11 @@ import org.hibernate.loader.ast.spi.SqlInPredicateMultiKeyLoader;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
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.JdbcParameterBindingsImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -51,7 +51,7 @@ public class EntityBatchLoaderInPredicate<T>
private final int domainBatchSize;
private final int sqlBatchSize;
private List<JdbcParameter> jdbcParameters;
private JdbcParametersList jdbcParameters;
private SelectStatement sqlAst;
private JdbcOperationQuerySelect jdbcSelectOperation;
@ -245,7 +245,7 @@ public class EntityBatchLoaderInPredicate<T>
EntityMappingType entityMapping,
int startIndex,
int numberOfKeys,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
SelectStatement sqlAst,
JdbcOperationQuerySelect jdbcSelectOperation,
Object pkValue,
@ -320,7 +320,8 @@ public class EntityBatchLoaderInPredicate<T>
final int expectedNumberOfParameters = identifierMapping.getJdbcTypeCount() * sqlBatchSize;
jdbcParameters = arrayList( expectedNumberOfParameters );
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder( expectedNumberOfParameters );
sqlAst = LoaderSelectBuilder.createSelect(
getLoadable(),
// null here means to select everything
@ -330,9 +331,10 @@ public class EntityBatchLoaderInPredicate<T>
sqlBatchSize,
LoadQueryInfluencers.NONE,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
this.jdbcParameters = jdbcParametersBuilder.build();
assert jdbcParameters.size() == expectedNumberOfParameters;
jdbcSelectOperation = sessionFactory.getJdbcServices()

View File

@ -33,6 +33,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.type.descriptor.java.JavaType;
@ -207,7 +208,7 @@ public class LoaderHelper {
final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler(
session.getPersistenceContext().getBatchFetchQueue(),
sqlAst,
Collections.singletonList( jdbcParameter ),
JdbcParametersList.singleton( jdbcParameter ),
jdbcParameterBindings
);

View File

@ -38,6 +38,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.type.BasicType;
@ -180,7 +181,7 @@ public class MultiIdEntityLoaderArrayParam<E> extends AbstractMultiIdEntityLoade
final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler(
batchFetchQueue,
sqlAst,
Collections.singletonList( jdbcParameter ),
JdbcParametersList.singleton( jdbcParameter ),
jdbcParameterBindings
);

View File

@ -37,6 +37,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -212,7 +213,7 @@ public class MultiIdEntityLoaderStandard<T> extends AbstractMultiIdEntityLoader<
log.tracef( "#loadEntitiesById(`%s`, `%s`, ..)", getLoadable().getEntityName(), numberOfIdsInBatch );
}
final List<JdbcParameter> jdbcParameters = new ArrayList<>( numberOfIdsInBatch * idJdbcTypeCount);
JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder( numberOfIdsInBatch * idJdbcTypeCount );
final SelectStatement sqlAst = LoaderSelectBuilder.createSelect(
getLoadable(),
@ -223,9 +224,10 @@ public class MultiIdEntityLoaderStandard<T> extends AbstractMultiIdEntityLoader<
numberOfIdsInBatch,
session.getLoadQueryInfluencers(),
lockOptions,
jdbcParameters::add,
jdbcParametersBuilder::add,
getSessionFactory()
);
JdbcParametersList jdbcParameters = jdbcParametersBuilder.build();
final JdbcServices jdbcServices = getSessionFactory().getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();

View File

@ -16,6 +16,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.ExecutionContext;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -53,7 +54,7 @@ public class MultiKeyLoadChunker<K> {
private final int keyColumnCount;
private final Bindable bindable;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
private final SelectStatement sqlAst;
private final JdbcOperationQuerySelect jdbcSelect;
@ -61,7 +62,7 @@ public class MultiKeyLoadChunker<K> {
int chunkSize,
int keyColumnCount,
Bindable bindable,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
SelectStatement sqlAst,
JdbcOperationQuerySelect jdbcSelect) {
this.chunkSize = chunkSize;

View File

@ -27,6 +27,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -50,7 +51,7 @@ public class MultiNaturalIdLoadingBatcher {
private final EntityMappingType entityDescriptor;
private final SelectStatement sqlSelect;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
private final KeyValueResolver keyValueResolver;
@ -65,8 +66,8 @@ public class MultiNaturalIdLoadingBatcher {
LockOptions lockOptions,
SessionFactoryImplementor sessionFactory) {
this.entityDescriptor = entityDescriptor;
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
jdbcParameters = new ArrayList<>( batchSize );
sqlSelect = LoaderSelectBuilder.createSelect(
entityDescriptor,
// return the full entity rather than parts
@ -77,9 +78,10 @@ public class MultiNaturalIdLoadingBatcher {
batchSize,
loadQueryInfluencers,
lockOptions,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
this.jdbcParameters = jdbcParametersBuilder.build();
this.keyValueResolver = keyValueResolver;

View File

@ -14,6 +14,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
import org.hibernate.sql.results.spi.RowTransformer;
@ -28,7 +29,7 @@ public class SingleIdArrayLoadPlan extends SingleIdLoadPlan<Object[]> {
EntityMappingType entityMappingType,
ModelPart restrictivePart,
SelectStatement sqlAst,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
LockOptions lockOptions,
SessionFactoryImplementor sessionFactory) {
super( entityMappingType, restrictivePart, sqlAst, jdbcParameters, lockOptions, sessionFactory );

View File

@ -22,6 +22,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.exec.spi.JdbcParametersList;
/**
* Standard implementation of SingleIdEntityLoader
@ -175,7 +176,7 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
LoadQueryInfluencers queryInfluencers,
SessionFactoryImplementor sessionFactory) {
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
final SelectStatement sqlAst = LoaderSelectBuilder.createSelect(
getLoadable(),
@ -186,10 +187,11 @@ public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSup
1,
queryInfluencers,
lockOptions,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
final JdbcParametersList jdbcParameters = jdbcParametersBuilder.build();
return new SingleIdLoadPlan<>(
(Loadable) getLoadable(),
getLoadable().getIdentifierMapping(),

View File

@ -28,6 +28,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.Callback;
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.results.internal.RowTransformerStandardImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.sql.results.spi.RowTransformer;
@ -46,13 +47,13 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
private final ModelPart restrictivePart;
private final LockOptions lockOptions;
private final JdbcOperationQuerySelect jdbcSelect;
private final List<JdbcParameter> jdbcParameters;
private final JdbcParametersList jdbcParameters;
public SingleIdLoadPlan(
EntityMappingType entityMappingType,
ModelPart restrictivePart,
SelectStatement sqlAst,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
LockOptions lockOptions,
SessionFactoryImplementor sessionFactory) {
this.entityMappingType = entityMappingType;
@ -78,7 +79,7 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
return lockOptions;
}
protected List<JdbcParameter> getJdbcParameters() {
protected JdbcParametersList getJdbcParameters() {
return jdbcParameters;
}

View File

@ -32,6 +32,7 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.Callback;
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.results.spi.ListResultsConsumer;
/**
@ -67,7 +68,7 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
final SessionFactoryImplementor sessionFactory = session.getFactory();
// todo (6.0) : cache the SQL AST and JdbcParameters
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
JdbcParametersList.Builder builder = JdbcParametersList.newBuilder();
final SelectStatement sqlAst = LoaderSelectBuilder.createSelectByUniqueKey(
entityDescriptor,
Collections.emptyList(),
@ -75,13 +76,14 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
null,
LoadQueryInfluencers.NONE,
LockOptions.NONE,
jdbcParameters::add,
builder::add,
sessionFactory
);
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
JdbcParametersList jdbcParameters = builder.build();
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
@ -122,7 +124,7 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
final SessionFactoryImplementor sessionFactory = session.getFactory();
// todo (6.0) : cache the SQL AST and JdbcParameters
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
final JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
final SelectStatement sqlAst = LoaderSelectBuilder.createSelectByUniqueKey(
entityDescriptor,
Collections.singletonList( entityDescriptor.getIdentifierMapping() ),
@ -130,14 +132,14 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
null,
LoadQueryInfluencers.NONE,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
sessionFactory
);
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
final JdbcParametersList jdbcParameters = jdbcParametersBuilder.build();
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
ukValue,

View File

@ -27,6 +27,7 @@ import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import static org.hibernate.sql.results.spi.ListResultsConsumer.UniqueSemantic.FILTER;
@ -46,7 +47,7 @@ import static org.hibernate.sql.results.spi.ListResultsConsumer.UniqueSemantic.F
public class GeneratedValuesProcessor {
private final SelectStatement selectStatement;
private final List<AttributeMapping> generatedValuesToSelect;
private final List<JdbcParameter> jdbcParameters = new ArrayList<>();
private final JdbcParametersList jdbcParameters;
private final EntityMappingType entityDescriptor;
private final SessionFactoryImplementor sessionFactory;
@ -61,8 +62,11 @@ public class GeneratedValuesProcessor {
generatedValuesToSelect = getGeneratedAttributes( entityDescriptor, timing );
if ( generatedValuesToSelect.isEmpty() ) {
selectStatement = null;
this.jdbcParameters = JdbcParametersList.empty();
}
else {
JdbcParametersList.Builder builder = JdbcParametersList.newBuilder();
selectStatement = LoaderSelectBuilder.createSelect(
entityDescriptor,
generatedValuesToSelect,
@ -71,9 +75,10 @@ public class GeneratedValuesProcessor {
1,
LoadQueryInfluencers.NONE,
LockOptions.READ,
jdbcParameters::add,
builder::add,
sessionFactory
);
this.jdbcParameters = builder.build();
}
}
@ -148,7 +153,7 @@ public class GeneratedValuesProcessor {
return generatedValuesToSelect;
}
public List<JdbcParameter> getJdbcParameters() {
public JdbcParametersList getJdbcParameters() {
return jdbcParameters;
}

View File

@ -255,6 +255,7 @@ import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SelectClause;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.model.MutationOperationGroup;
import org.hibernate.sql.model.ast.builder.MutationGroupBuilder;
import org.hibernate.sql.results.graph.DomainResult;
@ -1180,7 +1181,7 @@ public abstract class AbstractEntityPersister
return null;
}
else {
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
JdbcParametersList.Builder jdbcParametersBuilder = JdbcParametersList.newBuilder();
final SelectStatement select = LoaderSelectBuilder.createSelect(
this,
partsToSelect,
@ -1189,9 +1190,10 @@ public abstract class AbstractEntityPersister
1,
LoadQueryInfluencers.NONE,
LockOptions.NONE,
jdbcParameters::add,
jdbcParametersBuilder::add,
factory
);
JdbcParametersList jdbcParameters = jdbcParametersBuilder.build();
return new SingleIdArrayLoadPlan(
this,
getIdentifierMapping(),

View File

@ -45,6 +45,7 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
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.graph.entity.LoadingEntityEntry;
import org.hibernate.sql.results.internal.RowTransformerArrayImpl;
@ -100,7 +101,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
final SubselectFetch.RegistrationHandler subSelectFetchKeyHandler = SubselectFetch.createRegistrationHandler(
session.getPersistenceContext().getBatchFetchQueue(),
sqmInterpretation.selectStatement,
Collections.emptyList(),
JdbcParametersList.empty(),
jdbcParameterBindings
);
@ -352,7 +353,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
sqmInterpretation.getSqlAst()
);
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref
= SqmUtil.generateJdbcParamsXref( domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam );
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(
executionContext.getQueryParameterBindings(),
@ -392,7 +393,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
private final SelectStatement selectStatement;
private final JdbcOperationQuerySelect jdbcSelect;
private final FromClauseAccess tableGroupAccess;
private final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref;
private final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref;
private final Map<SqmParameter<?>, MappingModelExpressible<?>> sqmParameterMappingModelTypes;
private transient JdbcParameterBindings firstParameterBindings;
@ -400,7 +401,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
SelectStatement selectStatement,
JdbcOperationQuerySelect jdbcSelect,
FromClauseAccess tableGroupAccess,
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref,
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref,
Map<SqmParameter<?>, MappingModelExpressible<?>> sqmParameterMappingModelTypes,
JdbcParameterBindings firstParameterBindings) {
this.selectStatement = selectStatement;
@ -423,7 +424,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
return tableGroupAccess;
}
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> getJdbcParamsXref() {
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> getJdbcParamsXref() {
return jdbcParamsXref;
}

View File

@ -39,6 +39,7 @@ import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.exec.spi.JdbcOperationQueryDelete;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
/**
@ -51,7 +52,7 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
private JdbcOperationQueryDelete jdbcDelete;
private SqmTranslation<DeleteStatement> sqmInterpretation;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref;
public SimpleDeleteQueryPlan(
EntityMappingType entityDescriptor,

View File

@ -30,6 +30,7 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.insert.InsertStatement;
import org.hibernate.sql.exec.spi.JdbcOperationQueryInsert;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
/**
* @author Gavin King
@ -41,7 +42,7 @@ public class SimpleInsertQueryPlan implements NonSelectQueryPlan {
private JdbcOperationQueryInsert jdbcInsert;
private FromClauseAccess tableGroupAccess;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref;
public SimpleInsertQueryPlan(
SqmInsertStatement<?> sqmInsert,

View File

@ -30,6 +30,7 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.update.UpdateStatement;
import org.hibernate.sql.exec.spi.JdbcOperationQueryUpdate;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcParametersList;
/**
* @author Steve Ebersole
@ -40,7 +41,7 @@ public class SimpleUpdateQueryPlan implements NonSelectQueryPlan {
private JdbcOperationQueryUpdate jdbcUpdate;
private FromClauseAccess tableGroupAccess;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref;
private Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamsXref;
private Map<SqmParameter<?>, MappingModelExpressible<?>> sqmParamMappingTypeResolutions;
public SimpleUpdateQueryPlan(

View File

@ -31,6 +31,7 @@ import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.query.IllegalQueryOperationException;
@ -107,7 +108,7 @@ public class SqmUtil {
);
}
public static Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> generateJdbcParamsXref(
public static Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> generateJdbcParamsXref(
DomainParameterXref domainParameterXref,
JdbcParameterBySqmParameterAccess jdbcParameterBySqmParameterAccess) {
if ( domainParameterXref == null || !domainParameterXref.hasParameters() ) {
@ -115,24 +116,28 @@ public class SqmUtil {
}
final int queryParameterCount = domainParameterXref.getQueryParameterCount();
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> result = new IdentityHashMap<>( queryParameterCount );
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> result = new IdentityHashMap<>( queryParameterCount );
for ( Map.Entry<QueryParameterImplementor<?>, List<SqmParameter<?>>> entry : domainParameterXref.getSqmParamByQueryParam().entrySet() ) {
final QueryParameterImplementor<?> queryParam = entry.getKey();
final List<SqmParameter<?>> sqmParams = entry.getValue();
final Map<SqmParameter<?>, List<List<JdbcParameter>>> sqmParamMap = result.computeIfAbsent(
final Map<SqmParameter<?>, List<JdbcParametersList>> sqmParamMap = result.computeIfAbsent(
queryParam,
qp -> new IdentityHashMap<>( sqmParams.size() )
);
for ( SqmParameter<?> sqmParam : sqmParams ) {
sqmParamMap.put( sqmParam, jdbcParameterBySqmParameterAccess.getJdbcParamsBySqmParam().get( sqmParam ) );
List<List<JdbcParameter>> lists = jdbcParameterBySqmParameterAccess.getJdbcParamsBySqmParam().get(
sqmParam );
sqmParamMap.put( sqmParam, convert( lists ) );
final List<SqmParameter<?>> expansions = domainParameterXref.getExpansions( sqmParam );
if ( ! expansions.isEmpty() ) {
for ( SqmParameter<?> expansion : expansions ) {
sqmParamMap.put( expansion, jdbcParameterBySqmParameterAccess.getJdbcParamsBySqmParam().get( expansion ) );
List<List<JdbcParameter>> innerList = jdbcParameterBySqmParameterAccess.getJdbcParamsBySqmParam()
.get( expansion );
sqmParamMap.put( expansion, convert( innerList) );
result.put( queryParam, sqmParamMap );
}
}
@ -142,6 +147,17 @@ public class SqmUtil {
return result;
}
private static List<JdbcParametersList> convert(final List<List<JdbcParameter>> lists) {
if ( lists == null ) {
return null;
}
List<JdbcParametersList> output = new ArrayList<>( lists.size() );
for ( List<JdbcParameter> element : lists ) {
output.add( JdbcParametersList.fromList( element ) );
}
return output;
}
// public static JdbcParameterBindings buildJdbcParameterBindings(
// SqmStatement sqmStatement,
// JdbcParameterBySqmParameterAccess sqmInterpretation,
@ -185,7 +201,7 @@ public class SqmUtil {
public static JdbcParameterBindings createJdbcParameterBindings(
QueryParameterBindings domainParamBindings,
DomainParameterXref domainParameterXref,
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamXref,
Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<JdbcParametersList>>> jdbcParamXref,
MappingMetamodel domainModel,
Function<NavigablePath, TableGroup> tableGroupLocator,
SqmParameterMappingModelResolutionAccess mappingModelResolutionAccess,
@ -201,7 +217,7 @@ public class SqmUtil {
final QueryParameterBinding<?> domainParamBinding = domainParamBindings.getBinding( queryParam );
final Map<SqmParameter<?>, List<List<JdbcParameter>>> jdbcParamMap = jdbcParamXref.get( queryParam );
final Map<SqmParameter<?>, List<JdbcParametersList>> jdbcParamMap = jdbcParamXref.get( queryParam );
for ( SqmParameter<?> sqmParameter : sqmParameters ) {
final MappingModelExpressible resolvedMappingModelType = mappingModelResolutionAccess
.getResolvedMappingModelType( sqmParameter );
@ -216,7 +232,7 @@ public class SqmUtil {
session.getFactory()
);
final List<List<JdbcParameter>> jdbcParamsBinds = jdbcParamMap.get( sqmParameter );
final List<JdbcParametersList> jdbcParamsBinds = jdbcParamMap.get( sqmParameter );
if ( jdbcParamsBinds == null ) {
// This can happen when a group or order by item expression, that contains parameters,
// is replaced with an alias reference expression, which can happen for JPA Criteria queries
@ -224,7 +240,7 @@ public class SqmUtil {
}
if ( !domainParamBinding.isBound() ) {
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
parameterType.forEachJdbcType(
(position, jdbcMapping) -> {
jdbcParameterBindings.addBinding(
@ -241,7 +257,7 @@ public class SqmUtil {
// the original SqmParameter is the one we are processing.. create a binding for it..
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
createValueBindings(
jdbcParameterBindings,
queryParam,
@ -260,9 +276,9 @@ public class SqmUtil {
int expansionPosition = 0;
while ( valueItr.hasNext() ) {
final SqmParameter<?> expansionSqmParam = expansions.get( expansionPosition++ );
final List<List<JdbcParameter>> jdbcParamBinds = jdbcParamMap.get( expansionSqmParam );
final List<JdbcParametersList> jdbcParamBinds = jdbcParamMap.get( expansionSqmParam );
for ( int i = 0; i < jdbcParamBinds.size(); i++ ) {
List<JdbcParameter> expansionJdbcParams = jdbcParamBinds.get( i );
JdbcParametersList expansionJdbcParams = jdbcParamBinds.get( i );
createValueBindings(
jdbcParameterBindings,
queryParam, domainParamBinding,
@ -277,7 +293,7 @@ public class SqmUtil {
}
else if ( domainParamBinding.getBindValue() == null ) {
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
for ( int j = 0; j < jdbcParams.size(); j++ ) {
final JdbcParameter jdbcParameter = jdbcParams.get( j );
jdbcParameterBindings.addBinding(
@ -304,7 +320,7 @@ public class SqmUtil {
final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
assert jdbcParams.size() == 1;
final JdbcParameter jdbcParameter = jdbcParams.get( 0 );
jdbcParameterBindings.addBinding(
@ -318,7 +334,7 @@ public class SqmUtil {
final Object bindValue = domainParamBinding.getBindValue();
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
createValueBindings(
jdbcParameterBindings,
queryParam,
@ -342,7 +358,7 @@ public class SqmUtil {
QueryParameterImplementor<?> domainParam,
QueryParameterBinding<?> domainParamBinding,
Bindable parameterType,
List<JdbcParameter> jdbcParams,
JdbcParametersList jdbcParams,
Object bindValue,
Function<NavigablePath, TableGroup> tableGroupLocator,
SharedSessionContractImplementor session) {

View File

@ -64,7 +64,7 @@ public interface JdbcParameterBindings {
default int registerParametersForEachJdbcValue(
Object value,
Bindable bindable,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
SharedSessionContractImplementor session) {
return registerParametersForEachJdbcValue( value, 0, bindable, jdbcParameters, session );
}
@ -73,7 +73,7 @@ public interface JdbcParameterBindings {
Object value,
int offset,
Bindable bindable,
List<JdbcParameter> jdbcParameters,
JdbcParametersList jdbcParameters,
SharedSessionContractImplementor session) {
return bindable.forEachJdbcValue(
value,
@ -87,7 +87,7 @@ public interface JdbcParameterBindings {
private void createAndAddBinding(
int selectionIndex,
List<JdbcParameter> params,
JdbcParametersList params,
TypeConfiguration typeConfiguration,
Object jdbcValue,
JdbcMapping type) {

View File

@ -0,0 +1,124 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.exec.spi;
import java.util.List;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
/**
* Conceptually similar to a List of JdbcParameters, but exposing a
* read-only immutable contract.
* Also as nice side effect, avoid any potential type pollution
* problems during access.
*/
public interface JdbcParametersList {
static final JdbcParametersList EMPTY = new JdbcParametersListMulti( new JdbcParameter[]{} );
public JdbcParameter get(int selectionIndex);
public int size();
public static Builder newBuilder() {
return newBuilder( 2 );
}
public static JdbcParametersList fromList(final List<JdbcParameter> originalList) {
final Builder builder = newBuilder( originalList.size() );
for ( JdbcParameter element : originalList ) {
builder.add( element );
}
return builder.build();
}
public static JdbcParametersList empty() {
return EMPTY;
}
public static JdbcParametersList singleton(final JdbcParameter p) {
return new JdbcParametersListSingleton( p );
}
public static Builder newBuilder(final int i) {
return new Builder( i );
}
public static class Builder {
private JdbcParameter[] array;
private int index = 0;
private Builder(final int sizeEstimate) {
this.array = new JdbcParameter[sizeEstimate];
}
public void add(final JdbcParameter jdbcParameter) {
if ( index >= array.length ) {
int newSize = Math.max( index + 2, array.length >> 1 );
JdbcParameter[] newArray = new JdbcParameter[newSize];
System.arraycopy( array, 0, newArray, 0, array.length );
this.array = newArray;
}
this.array[index++] = jdbcParameter;
}
public JdbcParametersList build() {
if ( index == 0 ) {
return EMPTY;
}
else if ( index == 1 ) {
return singleton( array[0] );
}
else if ( index == array.length ) {
return new JdbcParametersListMulti( array );
}
else {
JdbcParameter[] newArray = new JdbcParameter[index];
System.arraycopy( array, 0, newArray, 0, index );
return new JdbcParametersListMulti( newArray );
}
}
}
public final class JdbcParametersListMulti implements JdbcParametersList {
private final JdbcParameter[] array;
private JdbcParametersListMulti(JdbcParameter[] inputArray) {
this.array = inputArray;
}
public JdbcParameter get(int selectionIndex) {
return array[selectionIndex];
}
public int size() {
return array.length;
}
}
public final class JdbcParametersListSingleton implements JdbcParametersList {
private final JdbcParameter singleElement;
private JdbcParametersListSingleton(JdbcParameter singleElement) {
this.singleElement = singleElement;
}
public JdbcParameter get(int selectionIndex) {
if ( selectionIndex != 0 ) {
throw new ArrayIndexOutOfBoundsException( selectionIndex );
}
return singleElement;
}
public int size() {
return 1;
}
}
}

View File

@ -0,0 +1,126 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.test.customstructures;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
import org.hibernate.sql.exec.spi.JdbcParametersList;
import org.junit.Assert;
import org.junit.Test;
/**
* Unit tests for JdbcParametersList
*/
public class JdbcParameterListTest {
@Test
public void emptyConstant() {
final JdbcParametersList empty = JdbcParametersList.empty();
expectsEmpty( empty );
}
@Test
public void singleton() {
final JdbcParameterImpl element = makeJdbcParameterElement();
final JdbcParametersList singleton = JdbcParametersList.singleton( element );
expectsSize( 1, singleton );
Assert.assertSame( element, singleton.get( 0 ) );
}
@Test
public void emptyBuilderDefault() {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder();
expectsEmpty( builder.build() );
}
@Test
public void emptyBuilderSized() {
for ( int i = 0; i < 5; i++ ) {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder( i );
expectsEmpty( builder.build() );
}
}
@Test
public void singletonBuilderDefault() {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder();
verifyAsSingletonBuilder( builder );
}
private void verifyAsSingletonBuilder(JdbcParametersList.Builder builder) {
final JdbcParameterImpl element = makeJdbcParameterElement();
builder.add( element );
final JdbcParametersList built = builder.build();
expectsSize( 1, built );
Assert.assertSame( element, built.get( 0 ) );
}
@Test
public void singletonBuilderSized() {
for ( int i = 0; i < 5; i++ ) {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder( i );
verifyAsSingletonBuilder( builder );
}
}
@Test
public void multiBuilderDefault() {
for ( int size = 0; size < 15; size++ ) {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder();
verifyNparamBuilder( size, builder );
}
}
@Test
public void multiBuilderSized() {
for ( int hintSize = 0; hintSize < 5; hintSize++ ) {
for ( int size = 0; size < 15; size++ ) {
final JdbcParametersList.Builder builder = JdbcParametersList.newBuilder( hintSize );
verifyNparamBuilder( size, builder );
}
}
}
private void verifyNparamBuilder(final int size, final JdbcParametersList.Builder builder) {
final JdbcParameterImpl[] elements = new JdbcParameterImpl[size];
for ( int i = 0; i < size; i++ ) {
elements[i] = makeJdbcParameterElement();
}
for ( JdbcParameter element : elements ) {
builder.add( element );
}
final JdbcParametersList built = builder.build();
expectsSize( size, built );
for ( int i = 0; i < size; i++ ) {
Assert.assertSame( elements[i], built.get( i ) );
}
}
private static void expectsEmpty(JdbcParametersList empty) {
expectsSize( 0, empty );
}
private static void expectsSize(int size, JdbcParametersList list) {
Assert.assertEquals( size, list.size() );
for ( int i = 0; i < size; i++ ) {
Assert.assertNotNull( list.get( i ) );
}
if ( size == 0 ) {
Assert.assertSame( JdbcParametersList.empty(), list );
}
else if ( size == 1 ) {
Assert.assertTrue( list instanceof JdbcParametersList.JdbcParametersListSingleton );
}
Assert.assertThrows( ArrayIndexOutOfBoundsException.class, () -> list.get( size ) );
}
private static JdbcParameterImpl makeJdbcParameterElement() {
return new JdbcParameterImpl( null );
}
}