Skip to content

Commit 65b778d

Browse files
committed
Don't change result type of criteria query when changing select clause
1 parent df84bcd commit 65b778d

File tree

5 files changed

+28
-29
lines changed

5 files changed

+28
-29
lines changed

Diff for: hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,8 @@ else if (member instanceof Method) {
910910
}
911911

912912
public static boolean isClass(Class<?> resultClass) {
913-
return !resultClass.isArray()
913+
return resultClass != Object.class
914+
&& !resultClass.isArray()
914915
&& !resultClass.isPrimitive()
915916
&& !resultClass.isEnum()
916917
&& !resultClass.isInterface();

Diff for: hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ protected static <T> RowTransformer<T> determineRowTransformer(
225225
if ( queryOptions.getTupleTransformer() != null ) {
226226
return makeRowTransformerTupleTransformerAdapter( sqm, queryOptions );
227227
}
228-
else if ( resultClass == null ) {
228+
else if ( resultClass == null || resultClass == Object.class ) {
229229
return RowTransformerStandardImpl.instance();
230230
}
231231
else {

Diff for: hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public abstract class AbstractSqmSelectQuery<T>
4747
implements SqmSelectQuery<T> {
4848
private final Map<String, SqmCteStatement<?>> cteStatements;
4949
private SqmQueryPart<T> sqmQueryPart;
50-
private Class<T> resultType;
50+
private final Class<T> resultType;
5151

5252
public AbstractSqmSelectQuery(Class<T> resultType, NodeBuilder builder) {
5353
this( new SqmQuerySpec<>( builder ), resultType, builder );
@@ -204,8 +204,12 @@ public Class<T> getResultType() {
204204
return resultType;
205205
}
206206

207+
/**
208+
* @deprecated Don't use this method. It has no effect.
209+
*/
210+
@Deprecated(forRemoval = true)
207211
protected void setResultType(Class<T> resultType) {
208-
this.resultType = resultType;
212+
// No-op
209213
}
210214

211215
@Override
@@ -412,7 +416,6 @@ protected Selection<? extends T> getResultSelection(Selection<?>[] selections) {
412416
break;
413417
}
414418
default: {
415-
setResultType( (Class<T>) Object[].class );
416419
resultSelection = ( Selection<? extends T> ) nodeBuilder().array( selections );
417420
}
418421
}

Diff for: hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java

+19-20
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ public SqmSelectStatement<T> copy(SqmCopyContext context) {
119119
if ( existing != null ) {
120120
return existing;
121121
}
122+
return createCopy( context, getResultType() );
123+
}
124+
125+
private <X> SqmSelectStatement<X> createCopy(SqmCopyContext context, Class<X> resultType) {
122126
final Set<SqmParameter<?>> parameters;
123127
if ( this.parameters == null ) {
124128
parameters = null;
@@ -129,17 +133,19 @@ public SqmSelectStatement<T> copy(SqmCopyContext context) {
129133
parameters.add( parameter.copy( context ) );
130134
}
131135
}
132-
final SqmSelectStatement<T> statement = context.registerCopy(
136+
//noinspection unchecked
137+
final SqmSelectStatement<X> statement = (SqmSelectStatement<X>) context.registerCopy(
133138
this,
134139
new SqmSelectStatement<>(
135140
nodeBuilder(),
136141
copyCteStatements( context ),
137-
getResultType(),
142+
resultType,
138143
getQuerySource(),
139144
parameters
140145
)
141146
);
142-
statement.setQueryPart( getQueryPart().copy( context ) );
147+
//noinspection unchecked
148+
statement.setQueryPart( (SqmQueryPart<X>) getQueryPart().copy( context ) );
143149
return statement;
144150
}
145151

@@ -266,9 +272,6 @@ public SqmSelectStatement<T> select(Selection<? extends T> selection) {
266272
checkSelectionIsJpaCompliant( selection );
267273
}
268274
getQuerySpec().setSelection( (JpaSelection<T>) selection );
269-
if ( getResultType() == Object.class ) {
270-
setResultType( (Class<T>) selection.getJavaType() );
271-
}
272275
return this;
273276
}
274277

@@ -313,7 +316,6 @@ private Selection<? extends T> getResultSelection(List<?> selectionList) {
313316
return (Selection<? extends T>) selectionList.get( 0 );
314317
}
315318
default: {
316-
setResultType( (Class<T>) Object[].class );
317319
return (Selection<? extends T>) nodeBuilder().array( selections );
318320
}
319321
}
@@ -461,14 +463,14 @@ private void validateComplianceFetchOffset() {
461463

462464
@Override
463465
public SqmSelectStatement<Long> createCountQuery() {
464-
final SqmSelectStatement<?> copy = copy( noParamCopyContext() );
465-
final SqmQuerySpec<?> querySpec = copy.getQuerySpec();
466-
final SqmQueryPart<?> queryPart = copy.getQueryPart();
466+
final SqmSelectStatement<Long> copy = createCopy( noParamCopyContext(), Long.class );
467+
final SqmQueryPart<?> queryPart = getQueryPart();
468+
final SqmQuerySpec<?> querySpec;
467469
//TODO: detect queries with no 'group by', but aggregate functions
468470
// in 'select' list (we don't even need to hit the database to
469471
// know they return exactly one row)
470472
if ( queryPart.isSimpleQueryPart()
471-
&& !querySpec.isDistinct()
473+
&& !( querySpec = (SqmQuerySpec<?>) queryPart ).isDistinct()
472474
&& querySpec.getGroupingExpressions().isEmpty() ) {
473475
for ( SqmRoot<?> root : querySpec.getRootList() ) {
474476
root.removeLeftFetchJoins();
@@ -478,24 +480,21 @@ public SqmSelectStatement<Long> createCountQuery() {
478480
querySpec.setOrderByClause( null );
479481
}
480482

481-
@SuppressWarnings("unchecked")
482-
final SqmSelectStatement<Long> statement = (SqmSelectStatement<Long>) copy;
483-
statement.setResultType( Long.class );
484-
return statement;
483+
return copy;
485484
}
486485
else {
487-
final JpaSelection<?> selection = querySpec.getSelection();
486+
final JpaSelection<?> selection = queryPart.getFirstQuerySpec().getSelection();
488487
if ( selection.isCompoundSelection() ) {
489488
char c = 'a';
490-
for ( JpaSelection<?> item: selection.getSelectionItems() ) {
491-
item.alias( Character.toString(++c) + '_' );
489+
for ( JpaSelection<?> item : selection.getSelectionItems() ) {
490+
item.alias( Character.toString( ++c ) + '_' );
492491
}
493492
}
494493
else {
495-
selection.alias("a_");
494+
selection.alias( "a_" );
496495
}
497496
final SqmSubQuery<?> subquery = new SqmSubQuery<>( copy, queryPart, null, nodeBuilder() );
498-
final SqmSelectStatement<Long> query = nodeBuilder().createQuery(Long.class);
497+
final SqmSelectStatement<Long> query = nodeBuilder().createQuery( Long.class );
499498
query.from( subquery );
500499
query.select( nodeBuilder().count() );
501500
return query;

Diff for: hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java

-4
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ public SqmSubQuery<T> multiselect(List<Selection<?>> selectionList) {
258258
break;
259259
}
260260
default: {
261-
setResultType( (Class<T>) Object[].class );
262261
resultSelection = ( Selection<? extends T> ) nodeBuilder().array( selections );
263262
}
264263
}
@@ -609,9 +608,6 @@ public SqmExpressible<T> getNodeType() {
609608
public void applyInferableType(SqmExpressible<?> type) {
610609
//noinspection unchecked
611610
expressibleType = (SqmExpressible<T>) type;
612-
if ( expressibleType != null && expressibleType.getExpressibleJavaType() != null ) {
613-
setResultType( expressibleType.getExpressibleJavaType().getJavaTypeClass() );
614-
}
615611
}
616612

617613
private void applyInferableType(Class<T> type) {

0 commit comments

Comments
 (0)