44 */
55package org .hibernate .query .sqm .internal ;
66
7+ import jakarta .persistence .TemporalType ;
78import org .hibernate .HibernateException ;
89import org .hibernate .engine .spi .SharedSessionContractImplementor ;
910import org .hibernate .graph .spi .AppliedGraph ;
11+ import org .hibernate .query .BindableType ;
1012import org .hibernate .query .IllegalSelectQueryException ;
1113import org .hibernate .query .KeyedPage ;
1214import org .hibernate .query .KeyedResultList ;
2325import org .hibernate .query .spi .ParameterMetadataImplementor ;
2426import org .hibernate .query .spi .QueryEngine ;
2527import org .hibernate .query .spi .QueryOptions ;
28+ import org .hibernate .query .spi .QueryParameterBinding ;
29+ import org .hibernate .query .spi .QueryParameterBindings ;
2630import org .hibernate .query .spi .SelectQueryPlan ;
31+ import org .hibernate .query .sqm .SqmQuerySource ;
2732import org .hibernate .query .sqm .spi .NamedSqmQueryMemento ;
2833import org .hibernate .query .sqm .tree .SqmStatement ;
34+ import org .hibernate .query .sqm .tree .expression .JpaCriteriaParameter ;
35+ import org .hibernate .query .sqm .tree .expression .SqmJpaCriteriaParameterWrapper ;
36+ import org .hibernate .query .sqm .tree .expression .SqmParameter ;
2937import org .hibernate .query .sqm .tree .from .SqmRoot ;
3038import org .hibernate .query .sqm .tree .select .SqmQueryGroup ;
3139import org .hibernate .query .sqm .tree .select .SqmQueryPart ;
@@ -118,9 +126,64 @@ private SqmSelectStatement<R> getSqmSelectStatement() {
118126 }
119127 }
120128
129+ protected void copyParameterBindings (QueryParameterBindings oldParameterBindings ) {
130+ final QueryParameterBindings parameterBindings = getQueryParameterBindings ();
131+ oldParameterBindings .visitBindings ( (queryParameter , binding ) -> {
132+ if ( binding .isBound () ) {
133+ //noinspection unchecked
134+ final QueryParameterBinding <Object > newBinding = (QueryParameterBinding <Object >) parameterBindings .getBinding ( queryParameter );
135+ //noinspection unchecked
136+ final BindableType <Object > bindType = (BindableType <Object >) binding .getBindType ();
137+ final TemporalType explicitTemporalPrecision = binding .getExplicitTemporalPrecision ();
138+ if ( binding .isMultiValued () ) {
139+ if ( explicitTemporalPrecision != null ) {
140+ newBinding .setBindValues ( binding .getBindValues (), explicitTemporalPrecision , getSessionFactory ().getTypeConfiguration () );
141+ }
142+ else if ( bindType != null ) {
143+ newBinding .setBindValues ( binding .getBindValues (), bindType );
144+ }
145+ else {
146+ newBinding .setBindValues ( binding .getBindValues () );
147+ }
148+ }
149+ else {
150+ if ( explicitTemporalPrecision != null ) {
151+ newBinding .setBindValue ( binding .getBindValue (), explicitTemporalPrecision );
152+ }
153+ else if ( bindType != null ) {
154+ newBinding .setBindValue ( binding .getBindValue (), bindType );
155+ }
156+ else {
157+ newBinding .setBindValue ( binding .getBindValue () );
158+ }
159+ }
160+ }
161+ } );
162+
163+ // Parameters might be created through HibernateCriteriaBuilder.value which we need to bind here
164+ for ( SqmParameter <?> sqmParameter : getDomainParameterXref ().getParameterResolutions ().getSqmParameters () ) {
165+ if ( sqmParameter instanceof SqmJpaCriteriaParameterWrapper <?> wrapper ) {
166+ bindCriteriaParameter ( wrapper );
167+ }
168+ }
169+ }
170+
171+ protected <T > void bindCriteriaParameter (SqmJpaCriteriaParameterWrapper <T > sqmParameter ) {
172+ final JpaCriteriaParameter <T > criteriaParameter = sqmParameter .getJpaCriteriaParameter ();
173+ final T value = criteriaParameter .getValue ();
174+ // We don't set a null value, unless the type is also null which
175+ // is the case when using HibernateCriteriaBuilder.value
176+ if ( value != null || criteriaParameter .getNodeType () == null ) {
177+ // Use the anticipated type for binding the value if possible
178+ getQueryParameterBindings ()
179+ .getBinding ( criteriaParameter )
180+ .setBindValue ( value , criteriaParameter .getAnticipatedType () );
181+ }
182+ }
183+
121184 @ Override
122185 public SelectionQuery <R > setOrder (List <? extends Order <? super R >> orderList ) {
123- final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext () );
186+ final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext ( SqmQuerySource . CRITERIA ) );
124187 selectStatement .orderBy ( orderList .stream ().map ( order -> sortSpecification ( selectStatement , order ) )
125188 .collect ( toList () ) );
126189 // TODO: when the QueryInterpretationCache can handle caching criteria queries,
@@ -133,7 +196,7 @@ public SelectionQuery<R> setOrder(List<? extends Order<? super R>> orderList) {
133196
134197 @ Override
135198 public SelectionQuery <R > setOrder (Order <? super R > order ) {
136- final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext () );
199+ final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext ( SqmQuerySource . CRITERIA ) );
137200 selectStatement .orderBy ( sortSpecification ( selectStatement , order ) );
138201 // TODO: when the QueryInterpretationCache can handle caching criteria queries,
139202 // simply cache the new SQM as if it were a criteria query, and remove this:
@@ -144,7 +207,7 @@ public SelectionQuery<R> setOrder(Order<? super R> order) {
144207
145208 @ Override
146209 public SelectionQuery <R > addRestriction (Restriction <? super R > restriction ) {
147- final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext () );
210+ final SqmSelectStatement <R > selectStatement = getSqmSelectStatement ().copy ( noParamCopyContext ( SqmQuerySource . CRITERIA ) );
148211 restriction .apply ( selectStatement , selectStatement .<R >getRoot ( 0 , getExpectedResultType () ) );
149212 // TODO: when the QueryInterpretationCache can handle caching criteria queries,
150213 // simply cache the new SQM as if it were a criteria query, and remove this:
0 commit comments