From 1a18df3b50cadb053c56d28293d65dd7f4055f91 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Mon, 17 Nov 2025 19:13:16 +0100 Subject: [PATCH 1/2] HHH-19895 Don't unnecessarily check values list support for insert/mutation CTE strategies --- .../query/sqm/mutation/internal/cte/CteInsertStrategy.java | 7 ------- .../sqm/mutation/internal/cte/CteMutationStrategy.java | 7 ------- 2 files changed, 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertStrategy.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertStrategy.java index a8bccd347820..5605abe65843 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertStrategy.java @@ -126,13 +126,6 @@ public CteInsertStrategy( ); } - if ( !dialect.supportsValuesList() ) { - throw new UnsupportedOperationException( - getClass().getSimpleName() + - " can only be used with Dialects that support VALUES lists" - ); - } - final PersistentClass persistentClass = runtimeModelCreationContext.getMetadata() .getEntityBinding( rootDescriptor.getEntityName() ); final Identifier tableNameIdentifier; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteMutationStrategy.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteMutationStrategy.java index bce9aa166d7d..7d53030403bb 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteMutationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteMutationStrategy.java @@ -80,13 +80,6 @@ public CteMutationStrategy( ); } - if ( !dialect.supportsValuesList() ) { - throw new UnsupportedOperationException( - getClass().getSimpleName() + - " can only be used with Dialects that support VALUES lists" - ); - } - this.idCteTable = CteTable.createIdTable( ID_TABLE_NAME, runtimeModelCreationContext.getMetadata().getEntityBinding( rootDescriptor.getEntityName() ) ); } From b1bb36b93d65b823d627533d710ab3bdac8c46e8 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Tue, 18 Nov 2025 12:35:50 +0100 Subject: [PATCH 2/2] HHH-19936 Ensure by-id parameters use SqlTypedMapping when possible --- .../internal/SqlAstBasedLockingStrategy.java | 9 +++-- .../temptable/TemporaryTableColumn.java | 36 ++++++++++++++++++- .../ast/internal/AbstractNaturalIdLoader.java | 4 +-- .../CollectionBatchLoaderArrayParam.java | 29 +++++++++------ .../internal/DatabaseSnapshotExecutor.java | 4 +-- .../internal/EntityBatchLoaderArrayParam.java | 31 ++++++++++------ .../ast/internal/LoaderSelectBuilder.java | 25 +++++++------ .../MultiIdEntityLoaderArrayParam.java | 35 +++++++++++++----- .../MultiNaturalIdLoaderArrayParam.java | 26 ++++++++++---- .../temptable/TableBasedDeleteHandler.java | 4 +-- .../temptable/TableBasedInsertHandler.java | 14 ++++---- .../TableBasedSoftDeleteHandler.java | 4 +-- .../temptable/TableBasedUpdateHandler.java | 4 +-- .../sqm/sql/BaseSqmToSqlAstConverter.java | 33 +---------------- .../sql/exec/internal/lock/LockingHelper.java | 14 ++++---- .../sql/exec/internal/lock/TableLock.java | 9 ++--- 16 files changed, 167 insertions(+), 114 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/SqlAstBasedLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/SqlAstBasedLockingStrategy.java index 5aa2f194e7a1..fef9582cd2af 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/SqlAstBasedLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/internal/SqlAstBasedLockingStrategy.java @@ -30,7 +30,7 @@ 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.lock.LockingHelper; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcSelect; @@ -216,8 +216,7 @@ private static void handleRestriction( LoaderSqlAstCreationState sqlAstCreationState, TableGroup rootTableGroup, JdbcParameterBindings jdbcParameterBindings) { - final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); rootQuerySpec.applyPredicate( new ComparisonPredicate( sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression( @@ -229,8 +228,8 @@ private static void handleRestriction( ) ); - jdbcParameterBindings.addBinding( jdbcParameter, - new JdbcParameterBindingImpl( jdbcMapping, value ) ); + final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); + jdbcParameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java index a78a71378263..68d5dd1c1642 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java @@ -6,6 +6,9 @@ import org.hibernate.engine.jdbc.Size; import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.SqlTypedMapping; + +import org.checkerframework.checker.nullness.qual.Nullable; /** * A column in a IdTable. As these columns mirror the entity id columns, we know a few things about it inherently, @@ -13,7 +16,7 @@ * * @author Steve Ebersole */ -public class TemporaryTableColumn { +public class TemporaryTableColumn implements SqlTypedMapping { private final TemporaryTable containingTable; private final String columnName; private final JdbcMapping jdbcMapping; @@ -57,6 +60,7 @@ public String getColumnName() { return columnName; } + @Override public JdbcMapping getJdbcMapping() { return jdbcMapping; } @@ -80,4 +84,34 @@ public boolean isNullable() { public boolean isPrimaryKey() { return primaryKey; } + + @Override + public @Nullable String getColumnDefinition() { + return sqlTypeName; + } + + @Override + public @Nullable Long getLength() { + return size.getLength(); + } + + @Override + public @Nullable Integer getArrayLength() { + return size.getArrayLength(); + } + + @Override + public @Nullable Integer getPrecision() { + return size.getPrecision(); + } + + @Override + public @Nullable Integer getScale() { + return size.getScale(); + } + + @Override + public @Nullable Integer getTemporalPrecision() { + return getJdbcMapping().getJdbcType().isTemporal() ? size.getPrecision() : null; + } } 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 b8e5529868fa..600074f7b0e3 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 @@ -35,7 +35,7 @@ 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.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.Callback; import org.hibernate.sql.exec.spi.JdbcParameterBinding; import org.hibernate.sql.exec.spi.JdbcParameterBindings; @@ -355,7 +355,7 @@ void applyRestriction( predicateConsumer.accept( new NullnessPredicate( columnReference ) ); } else { - final var jdbcParameter = new JdbcParameterImpl( jdbcValueMapping.getJdbcMapping() ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); final var predicate = new ComparisonPredicate( columnReference, ComparisonOperator.EQUAL, jdbcParameter ); predicateConsumer.accept( predicate ); 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 66280edf96f7..73bba982e746 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 @@ -16,14 +16,15 @@ import org.hibernate.loader.ast.spi.CollectionBatchLoader; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; -import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.metamodel.mapping.SqlTypedMapping; +import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; 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.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; -import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; @@ -44,7 +45,7 @@ public class CollectionBatchLoaderArrayParam extends AbstractCollectionBatchLoader implements SqlArrayMultiKeyLoader { - private final JdbcMapping arrayJdbcMapping; + private final SqlTypedMapping arraySqlTypedMapping; private final JdbcParameter jdbcParameter; private final SelectStatement sqlSelect; private final JdbcOperationQuerySelect jdbcSelectOperation; @@ -64,16 +65,24 @@ public CollectionBatchLoaderArrayParam( } final var keyDescriptor = getLoadable().getKeyDescriptor(); - final var jdbcMapping = keyDescriptor.getSingleJdbcMapping(); + final var selectable = keyDescriptor.getSelectable( 0 ); + final var jdbcMapping = selectable.getJdbcMapping(); final var jdbcJavaTypeClass = jdbcMapping.getJdbcJavaType().getJavaTypeClass(); - arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( - jdbcMapping, - jdbcJavaTypeClass, - getSessionFactory() + arraySqlTypedMapping = new SqlTypedMappingImpl( + selectable.getColumnDefinition(), + selectable.getLength(), + selectable.getPrecision(), + selectable.getScale(), + selectable.getTemporalPrecision(), + MultiKeyLoadHelper.resolveArrayJdbcMapping( + jdbcMapping, + jdbcJavaTypeClass, + getSessionFactory() + ) ); - jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + jdbcParameter = new SqlTypedMappingJdbcParameter( arraySqlTypedMapping ); sqlSelect = LoaderSelectBuilder.createSelectBySingleArrayParameter( getLoadable(), keyDescriptor.getKeyPart(), @@ -169,7 +178,7 @@ void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContract final var jdbcParameterBindings = new JdbcParameterBindingsImpl(1); jdbcParameterBindings.addBinding( jdbcParameter, - new JdbcParameterBindingImpl( arrayJdbcMapping, keysToInitialize ) + new JdbcParameterBindingImpl( arraySqlTypedMapping.getJdbcMapping(), keysToInitialize ) ); session.getJdbcServices().getJdbcSelectExecutor().list( 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 7571ee6b0e76..b41c3b261df4 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 @@ -24,7 +24,7 @@ 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.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.graph.DomainResult; @@ -100,7 +100,7 @@ class DatabaseSnapshotExecutor { final var tableReference = rootTableGroup.resolveTableReference( idNavigablePath, selection.getContainingTableExpression() ); - final var jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( selection ); jdbcParametersBuilder.add( jdbcParameter ); final var columnReference = (ColumnReference) 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 0d81e64b70b1..09322aa83d7d 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 @@ -11,14 +11,16 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; -import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.SelectableMapping; +import org.hibernate.metamodel.mapping.SqlTypedMapping; +import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; import static org.hibernate.loader.ast.internal.LoaderHelper.loadByArrayParameter; @@ -39,7 +41,7 @@ public class EntityBatchLoaderArrayParam implements SqlArrayMultiKeyLoader { private final int domainBatchSize; - private final JdbcMapping arrayJdbcMapping; + private final SqlTypedMapping arraySqlTypedMapping; private final JdbcParameter jdbcParameter; private final SelectStatement sqlAst; private final JdbcOperationQuerySelect jdbcSelectOperation; @@ -70,14 +72,23 @@ public EntityBatchLoaderArrayParam( ); } - final var identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); - arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( - identifierMapping.getJdbcMapping(), - identifierMapping.getJavaType().getJavaTypeClass(), - sessionFactory + final var identifierMapping = getLoadable().getIdentifierMapping(); + final SelectableMapping selectable = identifierMapping.getSelectable( 0 ); + final JdbcMapping jdbcMapping = selectable.getJdbcMapping(); + arraySqlTypedMapping = new SqlTypedMappingImpl( + selectable.getColumnDefinition(), + selectable.getLength(), + selectable.getPrecision(), + selectable.getScale(), + selectable.getTemporalPrecision(), + MultiKeyLoadHelper.resolveArrayJdbcMapping( + jdbcMapping, + jdbcMapping.getJdbcJavaType().getJavaTypeClass(), + sessionFactory + ) ); - jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + jdbcParameter = new SqlTypedMappingJdbcParameter( arraySqlTypedMapping ); sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( getLoadable(), identifierMapping, @@ -132,7 +143,7 @@ protected void initializeEntities( sqlAst, jdbcSelectOperation, jdbcParameter, - arrayJdbcMapping, + arraySqlTypedMapping.getJdbcMapping(), id, entityInstance, getLoadable().getRootEntityDescriptor(), 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 654d9aaedfe4..f0b9363a2734 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 @@ -58,7 +58,7 @@ import org.hibernate.sql.ast.tree.select.QueryPart; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; -import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.results.graph.BiDirectionalFetch; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.EntityGraphTraversalState; @@ -598,7 +598,7 @@ private void applyRestriction( (ColumnReference) sqlExpressionResolver.resolveSqlExpression( tableReference, selection ); if ( numberOfKeysToLoad == 1 ) { - final var jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( selection ); jdbcParameterConsumer.accept( jdbcParameter ); rootQuerySpec.applyPredicate( new ComparisonPredicate( columnRef, ComparisonOperator.EQUAL, jdbcParameter ) @@ -607,11 +607,9 @@ private void applyRestriction( else { final var predicate = new InListPredicate( columnRef ); for ( int i = 0; i < numberOfKeysToLoad; i++ ) { - for ( int j = 0; j < numberColumns; j++ ) { - final var jdbcParameter = new JdbcParameterImpl( columnRef.getJdbcMapping() ); - jdbcParameterConsumer.accept( jdbcParameter ); - predicate.addExpression( jdbcParameter ); - } + final var jdbcParameter = new SqlTypedMappingJdbcParameter( selection ); + jdbcParameterConsumer.accept( jdbcParameter ); + predicate.addExpression( jdbcParameter ); } rootQuerySpec.applyPredicate( predicate ); } @@ -638,12 +636,13 @@ private void applyRestriction( for ( int i = 0; i < numberOfKeysToLoad; i++ ) { final List tupleParams = new ArrayList<>( numberColumns ); - for ( int j = 0; j < numberColumns; j++ ) { - final ColumnReference columnReference = columnReferences.get( j ); - final JdbcParameter jdbcParameter = new JdbcParameterImpl( columnReference.getJdbcMapping() ); - jdbcParameterConsumer.accept( jdbcParameter ); - tupleParams.add( jdbcParameter ); - } + restrictedPart.forEachSelectable( + (columnIndex, selection) -> { + final JdbcParameter jdbcParameter = new SqlTypedMappingJdbcParameter( selection ); + jdbcParameterConsumer.accept( jdbcParameter ); + tupleParams.add( jdbcParameter ); + } + ); final SqlTuple paramTuple = new SqlTuple( tupleParams, restrictedPart ); predicate.addExpression( paramTuple ); } 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 8b8fa2b7e2a2..8d3e2d8618e9 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 @@ -16,14 +16,18 @@ import org.hibernate.loader.ast.spi.MultiIdLoadOptions; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; +import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.SelectableMapping; +import org.hibernate.metamodel.mapping.SqlTypedMapping; +import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptionsAdapter; import org.hibernate.sql.ast.tree.expression.JdbcParameter; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.sql.results.internal.RowTransformerStandardImpl; import org.hibernate.sql.results.spi.ManagedResultConsumer; @@ -43,7 +47,7 @@ */ public class MultiIdEntityLoaderArrayParam extends AbstractMultiIdEntityLoader implements SqlArrayMultiKeyLoader { - private final JdbcMapping arrayJdbcMapping; + private final SqlTypedMapping arraySqlTypedMapping; private final JdbcParameter jdbcParameter; protected final Object[] idArray; @@ -52,11 +56,24 @@ public MultiIdEntityLoaderArrayParam( EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { super( entityDescriptor, sessionFactory ); + final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping(); + final SelectableMapping selectable = identifierMapping.getSelectable( 0 ); + final JdbcMapping jdbcMapping = selectable.getJdbcMapping(); final var idClass = identifierMapping.getJavaType().getJavaTypeClass(); idArray = (Object[]) Array.newInstance( idClass, 0 ); - arrayJdbcMapping = - resolveArrayJdbcMapping( getIdentifierMapping().getJdbcMapping(), idClass, getSessionFactory() ); - jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + arraySqlTypedMapping = new SqlTypedMappingImpl( + selectable.getColumnDefinition(), + selectable.getLength(), + selectable.getPrecision(), + selectable.getScale(), + selectable.getTemporalPrecision(), + resolveArrayJdbcMapping( + jdbcMapping, + jdbcMapping.getJdbcJavaType().getJavaTypeClass(), + sessionFactory + ) + ); + jdbcParameter = new SqlTypedMappingJdbcParameter( arraySqlTypedMapping ); } @Override @@ -90,8 +107,10 @@ protected void loadEntitiesById( ); final var bindings = new JdbcParameterBindingsImpl(1); - bindings.addBinding( jdbcParameter, - new JdbcParameterBindingImpl( arrayJdbcMapping, toIdArray( idsInBatch ) ) ); + bindings.addBinding( + jdbcParameter, + new JdbcParameterBindingImpl( arraySqlTypedMapping.getJdbcMapping(), toIdArray( idsInBatch ) ) + ); final var sqlAstTranslator = getSqlAstTranslatorFactory() @@ -156,7 +175,7 @@ protected void loadEntitiesWithUnresolvedIds( sqlAst, jdbcSelectOperation, jdbcParameter, - arrayJdbcMapping, + arraySqlTypedMapping.getJdbcMapping(), null, null, null, 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 d6d0e01babaf..39dc23766895 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 @@ -11,10 +11,13 @@ 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.SqlTypedMapping; import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; +import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl; import org.hibernate.query.spi.QueryOptionsAdapter; -import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import static org.hibernate.loader.ast.internal.LoaderHelper.loadByArrayParameter; @@ -47,12 +50,21 @@ public List loadEntitiesWithUnresolvedIds( LockOptions lockOptions, SharedSessionContractImplementor session) { final var factory = session.getFactory(); - final var arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( - getNaturalIdMapping().getSingleJdbcMapping(), - keyClass, - factory + final var selectable = getNaturalIdAttribute().getSelectable( 0 ); + final JdbcMapping jdbcMapping = selectable.getJdbcMapping(); + final SqlTypedMapping arraySqlTypedMapping = new SqlTypedMappingImpl( + selectable.getColumnDefinition(), + selectable.getLength(), + selectable.getPrecision(), + selectable.getScale(), + selectable.getTemporalPrecision(), + MultiKeyLoadHelper.resolveArrayJdbcMapping( + jdbcMapping, + jdbcMapping.getJdbcJavaType().getJavaTypeClass(), + factory + ) ); - final var jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( arraySqlTypedMapping ); final var sqlAst = LoaderSelectBuilder.createSelectBySingleArrayParameter( getLoadable(), getNaturalIdAttribute(), @@ -76,7 +88,7 @@ public LockOptions getLockOptions() { sqlAst, jdbcSelectOperation, jdbcParameter, - arrayJdbcMapping, + arraySqlTypedMapping.getJdbcMapping(), null, null, null, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedDeleteHandler.java index 34fbabb07a2a..f577c35aad04 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedDeleteHandler.java @@ -53,7 +53,7 @@ import org.hibernate.sql.ast.tree.select.QuerySpec; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcMutationExecutor; import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation; @@ -112,7 +112,7 @@ public TableBasedDeleteHandler( this.sessionUidParameter = null; } else { - this.sessionUidParameter = new JdbcParameterImpl( sessionUidColumn.getJdbcMapping() ); + this.sessionUidParameter = new SqlTypedMappingJdbcParameter( sessionUidColumn ); } final MultiTableSqmMutationConverter converter = new MultiTableSqmMutationConverter( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java index 77dd84d9e8f5..aa39b4c288c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java @@ -92,7 +92,7 @@ import org.hibernate.sql.ast.tree.update.UpdateStatement; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation; import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect; @@ -149,7 +149,7 @@ public TableBasedInsertHandler( this.sessionUidParameter = null; } else { - this.sessionUidParameter = new JdbcParameterImpl( sessionUidColumn.getJdbcMapping() ); + this.sessionUidParameter = new SqlTypedMappingJdbcParameter( sessionUidColumn ); } final SqmJdbcExecutionContextAdapter executionContext = SqmJdbcExecutionContextAdapter.omittingLockingAndPaging( context ); final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter( @@ -606,7 +606,7 @@ private RootTableInserter createRootTableInserter( new ComparisonPredicate( columnReference, ComparisonOperator.EQUAL, - new JdbcParameterImpl( identifierMapping.getJdbcMapping() ) + new SqlTypedMappingJdbcParameter( identifierMapping ) ) ); } @@ -643,7 +643,7 @@ private RootTableInserter createRootTableInserter( } if ( needsIdentifierGeneration( generator, assignsId ) ) { final BasicEntityIdentifierMapping basicIdentifierMapping = (BasicEntityIdentifierMapping) identifierMapping; - final JdbcParameter rootIdentity = new JdbcParameterImpl( basicIdentifierMapping.getJdbcMapping() ); + final JdbcParameter rootIdentity = new SqlTypedMappingJdbcParameter( basicIdentifierMapping ); final List temporaryTableAssignments = new ArrayList<>( 1 ); final ColumnReference idColumnReference = new ColumnReference( (String) null, basicIdentifierMapping ); temporaryTableAssignments.add( new Assignment( idColumnReference, rootIdentity ) ); @@ -651,7 +651,7 @@ private RootTableInserter createRootTableInserter( final int rowNumberIndex = entityTable.getColumns().size() - (entityTable.getSessionUidColumn() == null ? 1 : 2); final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get( rowNumberIndex ); - final JdbcParameter rowNumber = new JdbcParameterImpl( rowNumberColumn.getJdbcMapping() ); + final JdbcParameter rowNumber = new SqlTypedMappingJdbcParameter( rowNumberColumn ); final UpdateStatement updateStatement = new UpdateStatement( temporaryTableReference, @@ -748,8 +748,8 @@ private RootTableInserter createRootTableInserter( getPrimaryKeyTableColumns( getEntityDescriptor(), entityTable ); assert primaryKeyTableColumns.size() == 1; - final JdbcParameter entityIdentity = new JdbcParameterImpl( identifierMapping.getJdbcMapping() ); - final JdbcParameter rootIdentity = new JdbcParameterImpl( identifierMapping.getJdbcMapping() ); + final JdbcParameter entityIdentity = new SqlTypedMappingJdbcParameter( identifierMapping ); + final JdbcParameter rootIdentity = new SqlTypedMappingJdbcParameter( identifierMapping ); final List temporaryTableAssignments = new ArrayList<>( 1 ); temporaryTableAssignments.add( new Assignment( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedSoftDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedSoftDeleteHandler.java index daeebf3f560d..b78441d3779c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedSoftDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedSoftDeleteHandler.java @@ -46,7 +46,7 @@ import org.hibernate.sql.ast.tree.update.UpdateStatement; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.JdbcMutationExecutor; import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation; import org.hibernate.sql.exec.spi.JdbcParameterBindings; @@ -105,7 +105,7 @@ public TableBasedSoftDeleteHandler( this.sessionUidParameter = null; } else { - this.sessionUidParameter = new JdbcParameterImpl( sessionUidColumn.getJdbcMapping() ); + this.sessionUidParameter = new SqlTypedMappingJdbcParameter( sessionUidColumn ); } final MultiTableSqmMutationConverter converter = new MultiTableSqmMutationConverter( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java index 4f4ec4d2b008..32cb7f6423da 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java @@ -59,7 +59,7 @@ import org.hibernate.sql.ast.tree.update.Assignment; import org.hibernate.sql.ast.tree.update.UpdateStatement; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; -import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation; import org.hibernate.sql.exec.spi.JdbcParameterBindings; @@ -119,7 +119,7 @@ public TableBasedUpdateHandler( this.sessionUidParameter = null; } else { - this.sessionUidParameter = new JdbcParameterImpl( sessionUidColumn.getJdbcMapping() ); + this.sessionUidParameter = new SqlTypedMappingJdbcParameter( sessionUidColumn ); } final SessionFactoryImplementor sessionFactory = getSessionFactory(); final MappingMetamodel domainModel = sessionFactory.getMappingMetamodel(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index e372b307d99f..0bd126ebf994 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -5885,41 +5885,10 @@ protected Expression consumeSqmParameter( final QueryParameterImplementor queryParameter = domainParameterXref.getQueryParameter( sqmParameter ); final QueryParameterBinding binding = domainParameterBindings.getBinding( queryParameter ); - if ( binding.setType( valueMapping ) ) { - replaceJdbcParametersType( - sqmParameter, - domainParameterXref.getSqmParameters( queryParameter ), - valueMapping - ); - } + binding.setType( valueMapping ); return new SqmParameterInterpretation( jdbcParametersForSqm, valueMapping ); } - private void replaceJdbcParametersType( - SqmParameter sourceSqmParameter, - List> sqmParameters, - MappingModelExpressible valueMapping) { - final JdbcMapping jdbcMapping = valueMapping.getSingleJdbcMapping(); - for ( SqmParameter sqmParameter : sqmParameters ) { - if ( sqmParameter != sourceSqmParameter ) { - sqmParameterMappingModelTypes.put( sqmParameter, valueMapping ); - final List> jdbcParamsForSqmParameter = jdbcParamsBySqmParam.get( sqmParameter ); - if ( jdbcParamsForSqmParameter != null ) { - for ( List parameters : jdbcParamsForSqmParameter ) { - assert parameters.size() == 1; - final JdbcParameter jdbcParameter = parameters.get( 0 ); - if ( ( (SqlExpressible) jdbcParameter ).getJdbcMapping() != jdbcMapping ) { - final JdbcParameter newJdbcParameter = new JdbcParameterImpl( jdbcMapping ); - parameters.set( 0, newJdbcParameter ); - jdbcParameters.getJdbcParameters().remove( jdbcParameter ); - jdbcParameters.getJdbcParameters().add( newJdbcParameter ); - } - } - } - } - } - } - protected Expression consumeSqmParameter(SqmParameter sqmParameter) { if ( sqmParameter.allowMultiValuedBinding() ) { final QueryParameterImplementor domainParam = domainParameterXref.getQueryParameter( sqmParameter ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/LockingHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/LockingHelper.java index d483c0245eb7..c5e6a933013b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/LockingHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/LockingHelper.java @@ -33,7 +33,7 @@ import org.hibernate.sql.exec.internal.BaseExecutionContext; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.StandardStatementCreator; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcParameterBindings; @@ -108,7 +108,7 @@ public static void lockCollectionTable( final ComparisonPredicate restriction; if ( jdbcTypeCount == 1 ) { final var jdbcParameter = - new JdbcParameterImpl( keyPart.getSelectable( 0 ).getJdbcMapping() ); + new SqlTypedMappingJdbcParameter( keyPart.getSelectable( 0 ) ); keyDescriptor.breakDownJdbcValues( collectionToLock.getKey(), (valueIndex, value, jdbcValueMapping) -> { @@ -127,7 +127,7 @@ public static void lockCollectionTable( (valueIndex, value, jdbcValueMapping) -> { columnReferences.add( new ColumnReference( tableReference, jdbcValueMapping ) ); final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); jdbcParameters.add( jdbcParameter ); parameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); @@ -248,7 +248,7 @@ private static void applySimpleCollectionKeyTableLockRestrictions( collectionInstance.getKey(), (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); restriction.addExpression( jdbcParameter ); parameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); @@ -291,7 +291,7 @@ private static InListPredicate applyCompositeCollectionKeyTableLockRestrictions( collectionKeyValue, (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); jdbcParameters.add( jdbcParameter ); parameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); @@ -389,7 +389,7 @@ private static void applySimpleCollectionKeyTableLockRestrictions( collectionKey.getKey(), (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); restriction.addExpression( jdbcParameter ); parameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); @@ -427,7 +427,7 @@ private static InListPredicate applyCompositeCollectionKeyTableLockRestrictions( collectionKey.getKey(), (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); jdbcParameters.add( jdbcParameter ); parameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/TableLock.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/TableLock.java index 23d594fb8ff4..b51ba2db15d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/TableLock.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/TableLock.java @@ -17,6 +17,7 @@ import org.hibernate.query.spi.QueryOptions; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.ast.tree.expression.JdbcParameter; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.from.NamedTableReference; import org.hibernate.sql.ast.tree.from.TableGroup; @@ -29,7 +30,7 @@ import org.hibernate.sql.exec.internal.BaseExecutionContext; 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.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.internal.StandardStatementCreator; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.results.graph.DomainResult; @@ -196,7 +197,7 @@ private void applySimpleKeyRestriction(List entityKeys, SharedSession entityKey.getIdentifierValue(), (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); restriction.addExpression( jdbcParameter ); jdbcParameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) ); @@ -218,12 +219,12 @@ private void applyCompositeKeyRestriction(List entityKeys, SharedSess querySpec.applyPredicate( restriction ); entityKeys.forEach( (entityKey) -> { - final List valueParams = arrayList( tableDetails.getKeyDetails().getColumnCount() ); + final List valueParams = arrayList( tableDetails.getKeyDetails().getColumnCount() ); identifierMapping.breakDownJdbcValues( entityKey.getIdentifierValue(), (valueIndex, value, jdbcValueMapping) -> { final var jdbcMapping = jdbcValueMapping.getJdbcMapping(); - final var jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + final var jdbcParameter = new SqlTypedMappingJdbcParameter( jdbcValueMapping ); valueParams.add( jdbcParameter ); jdbcParameterBindings.addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, value ) );