diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java index 173e0204f7d9..499641be6512 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java @@ -99,10 +99,16 @@ */ public abstract class AbstractCommonQueryContract implements CommonQueryContract { private final SharedSessionContractImplementor session; - private final QueryOptionsImpl queryOptions = new QueryOptionsImpl(); + private final QueryOptionsImpl queryOptions; public AbstractCommonQueryContract(SharedSessionContractImplementor session) { this.session = session; + this.queryOptions = new QueryOptionsImpl(); + } + + protected AbstractCommonQueryContract(AbstractCommonQueryContract original) { + this.session = original.session; + this.queryOptions = original.queryOptions; } public SharedSessionContractImplementor getSession() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java index df42432cff0e..687302e2902b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java @@ -36,6 +36,7 @@ import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.QueryParameter; import org.hibernate.query.SelectionQuery; +import org.hibernate.query.internal.QueryOptionsImpl; import org.hibernate.query.internal.ScrollableResultsIterator; import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.sql.exec.internal.CallbackImpl; @@ -81,6 +82,12 @@ public AbstractSelectionQuery(SharedSessionContractImplementor session) { super( session ); } + protected AbstractSelectionQuery(AbstractSelectionQuery original) { + super( original ); + this.sessionFlushMode = original.sessionFlushMode; + this.sessionCacheMode = original.sessionCacheMode; + } + protected void applyOptions(NamedQueryMemento memento) { if ( memento.getHints() != null ) { memento.getHints().forEach( this::applyHint ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java index df1641792660..9fa7899fdedb 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java @@ -17,7 +17,6 @@ import java.util.Map; import java.util.Set; -import org.hibernate.Internal; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.query.NullPrecedence; @@ -33,7 +32,6 @@ import org.hibernate.query.criteria.JpaSelection; import org.hibernate.query.criteria.JpaSimpleCase; import org.hibernate.query.criteria.JpaWindow; -import org.hibernate.query.criteria.ValueHandlingMode; import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; import org.hibernate.query.sqm.tree.domain.SqmBagJoin; @@ -87,9 +85,6 @@ public interface NodeBuilder extends HibernateCriteriaBuilder { QueryEngine getQueryEngine(); - @Internal - ValueHandlingMode setCriteriaValueHandlingMode(ValueHandlingMode criteriaValueHandlingMode); - SqmTuple tuple( Class tupleType, SqmExpression... expressions); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/AbstractSqmSelectionQuery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/AbstractSqmSelectionQuery.java index e8f031d39ff3..420b0e9d7413 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/AbstractSqmSelectionQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/AbstractSqmSelectionQuery.java @@ -29,6 +29,7 @@ import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.SelectQueryPlan; import org.hibernate.query.sqm.NodeBuilder; +import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.from.SqmRoot; @@ -69,6 +70,10 @@ abstract class AbstractSqmSelectionQuery extends AbstractSelectionQuery { super(session); } + AbstractSqmSelectionQuery(AbstractSqmSelectionQuery original) { + super( original ); + } + protected int max(boolean hasLimit, SqmSelectStatement sqmStatement, List list) { return !hasLimit || getQueryOptions().getLimit().getMaxRows() == null ? getMaxRows( sqmStatement, list.size() ) @@ -158,46 +163,14 @@ public SelectionQuery setPage(Page page) { return this; } - private SqmSelectStatement> paginateQuery( - List> keyDefinition, List> keyValues) { - @SuppressWarnings("unchecked") - final SqmSelectStatement> sqm = - (SqmSelectStatement>) - getSqmSelectStatement().copy( noParamCopyContext() ); - final NodeBuilder builder = sqm.nodeBuilder(); - //TODO: find a better way handle parameters - final ValueHandlingMode valueHandlingMode = builder.setCriteriaValueHandlingMode(ValueHandlingMode.INLINE); - try { - return paginate( keyDefinition, keyValues, sqm, builder ); - } - finally { - builder.setCriteriaValueHandlingMode( valueHandlingMode ); - } - } - - @Override public KeyedResultList getKeyedResultList(KeyedPage keyedPage) { if ( keyedPage == null ) { throw new IllegalArgumentException( "KeyedPage was null" ); } + final List> results = new SqmSelectionQueryImpl>( this, keyedPage ) + .getResultList(); final Page page = keyedPage.getPage(); - final List> key = keyedPage.getKey(); - final List> keyDefinition = keyedPage.getKeyDefinition(); - final List> appliedKeyDefinition = - keyedPage.getKeyInterpretation() == KEY_OF_FIRST_ON_NEXT_PAGE - ? Order.reverse(keyDefinition) : keyDefinition; - - setMaxResults( page.getMaxResults() + 1 ); - if ( key == null ) { - setFirstResult( page.getFirstResult() ); - } - -// getQueryOptions().setQueryPlanCachingEnabled( false ); - final List> results = - buildConcreteQueryPlan( paginateQuery( appliedKeyDefinition, key ), getQueryOptions() ) - .performList(this); - return new KeyedResultList<>( collectResults( results, page.getSize(), keyedPage.getKeyInterpretation() ), collectKeys( results, page.getSize() ), @@ -281,10 +254,6 @@ protected ConcreteSqmSelectQueryPlan buildConcreteQueryPlan( ); } - private SelectQueryPlan buildConcreteQueryPlan(SqmSelectStatement sqmStatement, QueryOptions options) { - return buildConcreteQueryPlan( sqmStatement, null, null, options ); - } - protected void applyOptions(NamedSqmQueryMemento memento) { applyOptions( (NamedQueryMemento) memento ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/KeyBasedPagination.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/KeyBasedPagination.java index f1eb6eabab1d..098f3ec442f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/KeyBasedPagination.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/KeyBasedPagination.java @@ -118,11 +118,6 @@ private static > SqmPredicate keyPredicate( Expression key, C keyValue, SortDirection direction, List> previousKeys, List> keyValues, NodeBuilder builder) { - // TODO: use a parameter here and create a binding for it -// @SuppressWarnings("unchecked") -// final Class valueClass = (Class) keyValue.getClass(); -// final JpaParameterExpression parameter = builder.parameter(valueClass); -// setParameter( parameter, keyValue ); SqmPredicate predicate; switch ( direction ) { case ASCENDING: diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/NoParamSqmCopyContext.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/NoParamSqmCopyContext.java index 8a3d960a2a05..ae8f09f48b39 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/NoParamSqmCopyContext.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/NoParamSqmCopyContext.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.sqm.internal; +import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.checkerframework.checker.nullness.qual.Nullable; @@ -14,6 +15,13 @@ * @author Marco Belladelli */ public class NoParamSqmCopyContext extends SimpleSqmCopyContext { + public NoParamSqmCopyContext() { + } + + public NoParamSqmCopyContext(@Nullable SqmQuerySource querySource) { + super( querySource ); + } + @Override public @Nullable T getCopy(T original) { if ( original instanceof SqmParameter ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmCopyContext.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmCopyContext.java index 37e61b8d4145..0a3c20cbb051 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmCopyContext.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmCopyContext.java @@ -8,6 +8,7 @@ import java.util.IdentityHashMap; +import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.checkerframework.checker.nullness.qual.Nullable; @@ -17,6 +18,15 @@ */ public class SimpleSqmCopyContext implements SqmCopyContext { private final IdentityHashMap map = new IdentityHashMap<>(); + private final @Nullable SqmQuerySource querySource; + + public SimpleSqmCopyContext() { + this( null ); + } + + public SimpleSqmCopyContext(@Nullable SqmQuerySource querySource) { + this.querySource = querySource; + } @Override @SuppressWarnings( "unchecked" ) @@ -32,4 +42,9 @@ public T registerCopy(T original, T copy) { } return copy; } + + @Override + public @Nullable SqmQuerySource getQuerySource() { + return querySource; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index fb72ec5e5ce4..632953b7e9b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -46,7 +46,6 @@ import org.hibernate.metamodel.model.domain.DomainType; import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; -import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl; import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.query.BindableType; @@ -199,7 +198,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, private final transient boolean jpaComplianceEnabled; private final transient QueryEngine queryEngine; private final transient Supplier sessionFactory; - private transient ValueHandlingMode criteriaValueHandlingMode; + private final transient ValueHandlingMode criteriaValueHandlingMode; private transient BasicType booleanType; private transient BasicType integerType; private transient BasicType longType; @@ -228,13 +227,6 @@ public SqmCriteriaNodeBuilder( } } - @Override - public ValueHandlingMode setCriteriaValueHandlingMode(ValueHandlingMode criteriaValueHandlingMode) { - ValueHandlingMode current = this.criteriaValueHandlingMode; - this.criteriaValueHandlingMode = criteriaValueHandlingMode; - return current; - } - @Override public JpaMetamodel getDomainModel() { return getSessionFactory().getJpaMetamodel(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java index 47b1ac97cb59..93684ecd65c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java @@ -30,7 +30,11 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.graph.spi.AppliedGraph; import org.hibernate.internal.util.collections.IdentitySet; +import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.query.BindableType; +import org.hibernate.query.KeyedPage; +import org.hibernate.query.Order; +import org.hibernate.query.Page; import org.hibernate.query.QueryParameter; import org.hibernate.query.criteria.internal.NamedCriteriaQueryMementoImpl; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; @@ -42,9 +46,11 @@ import org.hibernate.query.spi.ParameterMetadataImplementor; import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.ScrollableResultsImplementor; import org.hibernate.query.spi.SelectQueryPlan; +import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.SqmSelectionQuery; import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource; import org.hibernate.query.sqm.spi.SqmSelectionQueryImplementor; @@ -69,9 +75,12 @@ import static org.hibernate.jpa.LegacySpecHints.HINT_JAVAEE_CACHE_STORE_MODE; import static org.hibernate.jpa.SpecHints.HINT_SPEC_CACHE_RETRIEVE_MODE; import static org.hibernate.jpa.SpecHints.HINT_SPEC_CACHE_STORE_MODE; +import static org.hibernate.query.KeyedPage.KeyInterpretation.KEY_OF_FIRST_ON_NEXT_PAGE; import static org.hibernate.query.spi.SqlOmittingQueryOptions.omitSqlQueryOptions; +import static org.hibernate.query.sqm.internal.KeyBasedPagination.paginate; import static org.hibernate.query.sqm.internal.SqmInterpretationsKey.createInterpretationsKey; import static org.hibernate.query.sqm.internal.SqmUtil.isSelectionAssignableToResultType; +import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext; /** * @author Steve Ebersole @@ -179,6 +188,87 @@ public SqmSelectionQueryImpl( this.tupleMetadata = buildTupleMetadata( sqm, expectedResultType ); } + SqmSelectionQueryImpl(AbstractSqmSelectionQuery original, KeyedPage keyedPage) { + super( original ); + + final Page page = keyedPage.getPage(); + final List> key = keyedPage.getKey(); + final List> keyDefinition = keyedPage.getKeyDefinition(); + final List> appliedKeyDefinition = + keyedPage.getKeyInterpretation() == KEY_OF_FIRST_ON_NEXT_PAGE + ? Order.reverse( keyDefinition ) : keyDefinition; + + //noinspection unchecked + this.sqm = (SqmSelectStatement) paginate( + appliedKeyDefinition, + key, + // Change the query source to CRITERIA, because we will change the query and introduce parameters + (SqmSelectStatement>) original.getSqmStatement() + .copy( noParamCopyContext( SqmQuerySource.CRITERIA ) ), + original.getSqmStatement().nodeBuilder() + ); + this.hql = CRITERIA_HQL_STRING; + + this.domainParameterXref = DomainParameterXref.from( sqm ); + this.parameterMetadata = domainParameterXref.hasParameters() + ? new ParameterMetadataImpl( domainParameterXref.getQueryParameters() ) + : ParameterMetadataImpl.EMPTY; + + // Just use the original parameter bindings since this object is never going to be mutated + this.parameterBindings = parameterMetadata.createBindings( original.getSession().getSessionFactory() ); + // Don't remove this cast. This is here to work around this bug: https://bugs.openjdk.org/browse/JDK-8340443 + (( DomainQueryExecutionContext) original ).getQueryParameterBindings().visitBindings( + (parameter, binding) -> { + //noinspection unchecked + final QueryParameterBinding parameterBinding = + (QueryParameterBinding) this.parameterBindings.getBinding( parameter ); + //noinspection unchecked + final BindableType bindType = (BindableType) binding.getBindType(); + final TemporalType explicitTemporalPrecision = binding.getExplicitTemporalPrecision(); + if ( explicitTemporalPrecision != null ) { + if ( binding.isMultiValued() ) { + parameterBinding.setBindValues( + binding.getBindValues(), + explicitTemporalPrecision, + getSessionFactory().getTypeConfiguration() + ); + } + else { + parameterBinding.setBindValue( binding.getBindValue(), explicitTemporalPrecision ); + } + } + else { + if ( binding.isMultiValued() ) { + parameterBinding.setBindValues( binding.getBindValues(), bindType ); + } + else { + parameterBinding.setBindValue( binding.getBindValue(), bindType ); + } + } + //noinspection unchecked + parameterBinding.setType( (MappingModelExpressible) binding.getType() ); + } + ); + + // Parameters might be created through HibernateCriteriaBuilder.value which we need to bind here + for ( SqmParameter sqmParameter : domainParameterXref.getParameterResolutions().getSqmParameters() ) { + if ( sqmParameter instanceof SqmJpaCriteriaParameterWrapper ) { + bindCriteriaParameter( (SqmJpaCriteriaParameterWrapper) sqmParameter ); + } + } + + //noinspection unchecked + this.expectedResultType = (Class) KeyedResult.class; + this.resultType = determineResultType( sqm, expectedResultType ); + this.tupleMetadata = null; + + setMaxResults( page.getMaxResults() + 1 ); + if ( key == null ) { + setFirstResult( page.getFirstResult() ); + } + } + + private static Class determineResultType(SqmSelectStatement sqm, Class expectedResultType) { final List> selections = sqm.getQuerySpec().getSelectClause().getSelections(); if ( selections.size() == 1 ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmCopyContext.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmCopyContext.java index b57278264f01..fa1af21bbe23 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmCopyContext.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmCopyContext.java @@ -7,6 +7,7 @@ package org.hibernate.query.sqm.tree; import org.hibernate.Incubating; +import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.internal.NoParamSqmCopyContext; import org.hibernate.query.sqm.internal.SimpleSqmCopyContext; @@ -31,11 +32,30 @@ default boolean copyFetchedFlag() { return true; } + /** + * Returns the query source to use for copied queries. + * {@code null} means, that the original query source should be retained. + * + * @since 7.0 + */ + @Incubating + default @Nullable SqmQuerySource getQuerySource() { + return null; + } + static SqmCopyContext simpleContext() { return new SimpleSqmCopyContext(); } + static SqmCopyContext simpleContext(SqmQuerySource querySource) { + return new SimpleSqmCopyContext( querySource ); + } + static SqmCopyContext noParamCopyContext() { return new NoParamSqmCopyContext(); } + + static SqmCopyContext noParamCopyContext(SqmQuerySource querySource) { + return new NoParamSqmCopyContext( querySource ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java index 0acd3cee0075..c8cb931a1f48 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java @@ -93,7 +93,7 @@ public SqmDeleteStatement copy(SqmCopyContext context) { this, new SqmDeleteStatement<>( nodeBuilder(), - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), copyParameters( context ), copyCteStatements( context ), getTarget().copy( context ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java index 90d0396bf2a8..7cbc113f122b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java @@ -81,7 +81,7 @@ public SqmInsertSelectStatement copy(SqmCopyContext context) { this, new SqmInsertSelectStatement<>( nodeBuilder(), - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), copyParameters( context ), copyCteStatements( context ), getTarget().copy( context ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java index d51a1b097790..c4bad1806151 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java @@ -86,7 +86,7 @@ public SqmInsertValuesStatement copy(SqmCopyContext context) { this, new SqmInsertValuesStatement<>( nodeBuilder(), - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), copyParameters( context ), copyCteStatements( context ), getTarget().copy( context ), @@ -102,7 +102,7 @@ public SqmInsertValuesStatement copyWithoutValues(SqmCopyContext context) { this, new SqmInsertValuesStatement<>( nodeBuilder(), - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), copyParameters( context ), copyCteStatements( context ), getTarget().copy( context ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java index 631d3eeff92c..cb347a41ae91 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java @@ -140,7 +140,7 @@ private SqmSelectStatement createCopy(SqmCopyContext context, Class re nodeBuilder(), copyCteStatements( context ), resultType, - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), parameters ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java index f3accf2906c7..61721bb9566c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java @@ -107,7 +107,7 @@ public SqmUpdateStatement copy(SqmCopyContext context) { this, new SqmUpdateStatement<>( nodeBuilder(), - getQuerySource(), + context.getQuerySource() == null ? getQuerySource() : context.getQuerySource(), copyParameters( context ), copyCteStatements( context ), getTarget().copy( context )