4
4
*/
5
5
package org .hibernate .query .sqm .internal ;
6
6
7
+ import jakarta .persistence .TemporalType ;
7
8
import org .hibernate .HibernateException ;
8
9
import org .hibernate .engine .spi .SharedSessionContractImplementor ;
9
10
import org .hibernate .graph .spi .AppliedGraph ;
11
+ import org .hibernate .query .BindableType ;
10
12
import org .hibernate .query .IllegalSelectQueryException ;
11
13
import org .hibernate .query .KeyedPage ;
12
14
import org .hibernate .query .KeyedResultList ;
23
25
import org .hibernate .query .spi .ParameterMetadataImplementor ;
24
26
import org .hibernate .query .spi .QueryEngine ;
25
27
import org .hibernate .query .spi .QueryOptions ;
28
+ import org .hibernate .query .spi .QueryParameterBinding ;
29
+ import org .hibernate .query .spi .QueryParameterBindings ;
26
30
import org .hibernate .query .spi .SelectQueryPlan ;
31
+ import org .hibernate .query .sqm .SqmQuerySource ;
27
32
import org .hibernate .query .sqm .spi .NamedSqmQueryMemento ;
28
33
import 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 ;
29
37
import org .hibernate .query .sqm .tree .from .SqmRoot ;
30
38
import org .hibernate .query .sqm .tree .select .SqmQueryGroup ;
31
39
import org .hibernate .query .sqm .tree .select .SqmQueryPart ;
@@ -118,9 +126,64 @@ private SqmSelectStatement<R> getSqmSelectStatement() {
118
126
}
119
127
}
120
128
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
+
121
184
@ Override
122
185
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 ) );
124
187
selectStatement .orderBy ( orderList .stream ().map ( order -> sortSpecification ( selectStatement , order ) )
125
188
.collect ( toList () ) );
126
189
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
@@ -133,7 +196,7 @@ public SelectionQuery<R> setOrder(List<? extends Order<? super R>> orderList) {
133
196
134
197
@ Override
135
198
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 ) );
137
200
selectStatement .orderBy ( sortSpecification ( selectStatement , order ) );
138
201
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
139
202
// 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) {
144
207
145
208
@ Override
146
209
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 ) );
148
211
restriction .apply ( selectStatement , selectStatement .<R >getRoot ( 0 , getExpectedResultType () ) );
149
212
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
150
213
// simply cache the new SQM as if it were a criteria query, and remove this:
0 commit comments