Skip to content

Commit 124bb5a

Browse files
committed
HHH-19572 fix where(List) and having(List)
these new operations in JPA 3.2 were implemented incorrectly
1 parent b2c3297 commit 124bb5a

File tree

8 files changed

+127
-62
lines changed

8 files changed

+127
-62
lines changed

hibernate-core/src/main/java/org/hibernate/query/criteria/JpaQueryStructure.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public interface JpaQueryStructure<T> extends JpaQueryPart<T> {
6060

6161
JpaQueryStructure<T> setRestriction(Predicate... restrictions);
6262

63+
JpaQueryStructure<T> setRestriction(List<Predicate> restrictions);
64+
6365

6466
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6567
// Grouping (group-by / having) clause
@@ -78,6 +80,8 @@ public interface JpaQueryStructure<T> extends JpaQueryPart<T> {
7880

7981
JpaQueryStructure<T> setGroupRestriction(Predicate... restrictions);
8082

83+
JpaQueryStructure<T> setGroupRestriction(List<Predicate> restrictions);
84+
8185
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8286
// Covariant overrides
8387

hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,9 +972,11 @@ <T> SqmJsonValueExpression<T> jsonValue(
972972
@Override
973973
SqmPredicate wrap(Expression<Boolean> expression);
974974

975-
@Override
975+
@Override @SuppressWarnings("unchecked")
976976
SqmPredicate wrap(Expression<Boolean>... expressions);
977977

978+
SqmPredicate wrap(List<? extends Expression<Boolean>> restrictions);
979+
978980
@Override
979981
<P, F> SqmExpression<F> fk(Path<P> path);
980982

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,19 @@ public final SqmPredicate wrap(Expression<Boolean>... expressions) {
596596
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
597597
}
598598

599+
@Override
600+
public SqmPredicate wrap(List<? extends Expression<Boolean>> restrictions) {
601+
if ( restrictions.size() == 1 ) {
602+
return wrap( restrictions.get( 0 ) );
603+
}
604+
605+
final List<SqmPredicate> predicates = new ArrayList<>( restrictions.size() );
606+
for ( Expression<Boolean> expression : restrictions ) {
607+
predicates.add( wrap( expression ) );
608+
}
609+
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
610+
}
611+
599612
@Override @SuppressWarnings("unchecked")
600613
public <T extends HibernateCriteriaBuilder> T unwrap(Class<T> clazz) {
601614
return (T) extensions.get( clazz );

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmWhereClause.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,10 @@ public void setPredicate(SqmPredicate predicate) {
4545

4646
@Override
4747
public void applyPredicate(SqmPredicate predicate) {
48-
if ( this.predicate == null ) {
49-
this.predicate = predicate;
50-
}
51-
else {
52-
this.predicate = nodeBuilder.and( this.predicate, predicate );
53-
}
48+
this.predicate =
49+
this.predicate == null
50+
? predicate
51+
: nodeBuilder.and( this.predicate, predicate );
5452
}
5553

5654
@Override

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ public SqmSelectQuery<T> where(Predicate... restrictions) {
366366
return this;
367367
}
368368

369+
@Override
370+
public SqmSelectQuery<T> where(List<Predicate> restrictions) {
371+
getQuerySpec().setRestriction( restrictions );
372+
return this;
373+
}
374+
369375

370376
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
371377
// Grouping
@@ -377,7 +383,7 @@ public List<Expression<?>> getGroupList() {
377383

378384
@Override
379385
public SqmSelectQuery<T> groupBy(Expression<?>... expressions) {
380-
getQuerySpec().setGroupingExpressions( List.of( expressions ) );
386+
getQuerySpec().setGroupingExpressions( expressions );
381387
return this;
382388
}
383389

@@ -394,13 +400,19 @@ public SqmPredicate getGroupRestriction() {
394400

395401
@Override
396402
public SqmSelectQuery<T> having(Expression<Boolean> booleanExpression) {
397-
getQuerySpec().setGroupRestriction( nodeBuilder().wrap( booleanExpression ) );
403+
getQuerySpec().setGroupRestriction( booleanExpression );
398404
return this;
399405
}
400406

401407
@Override
402408
public SqmSelectQuery<T> having(Predicate... predicates) {
403-
getQuerySpec().setGroupRestriction( nodeBuilder().wrap( predicates ) );
409+
getQuerySpec().setGroupRestriction( predicates );
410+
return this;
411+
}
412+
413+
@Override
414+
public AbstractQuery<T> having(List<Predicate> restrictions) {
415+
getQuerySpec().setGroupRestriction( restrictions );
404416
return this;
405417
}
406418

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,20 +374,44 @@ else if ( restrictions.length == 0 ) {
374374
setWhereClause( null );
375375
}
376376
else {
377-
SqmWhereClause whereClause = getWhereClause();
378-
if ( whereClause == null ) {
379-
setWhereClause( whereClause = new SqmWhereClause( nodeBuilder() ) );
380-
}
381-
else {
382-
whereClause.setPredicate( null );
377+
final SqmWhereClause whereClause = resetWhereClause();
378+
for ( Predicate restriction : restrictions ) {
379+
whereClause.applyPredicate( (SqmPredicate) restriction );
383380
}
381+
}
382+
return this;
383+
}
384+
385+
@Override
386+
public SqmQuerySpec<T> setRestriction(List<Predicate> restrictions) {
387+
if ( restrictions == null ) {
388+
throw new IllegalArgumentException( "The predicate list cannot be null" );
389+
}
390+
else if ( restrictions.isEmpty() ) {
391+
setWhereClause( null );
392+
}
393+
else {
394+
final SqmWhereClause whereClause = resetWhereClause();
384395
for ( Predicate restriction : restrictions ) {
385396
whereClause.applyPredicate( (SqmPredicate) restriction );
386397
}
387398
}
388399
return this;
389400
}
390401

402+
private SqmWhereClause resetWhereClause() {
403+
final SqmWhereClause whereClause = getWhereClause();
404+
if ( whereClause == null ) {
405+
final SqmWhereClause newWhereClause = new SqmWhereClause( nodeBuilder() );
406+
setWhereClause( newWhereClause );
407+
return newWhereClause;
408+
}
409+
else {
410+
whereClause.setPredicate( null );
411+
return whereClause;
412+
}
413+
}
414+
391415
@Override
392416
public List<SqmExpression<?>> getGroupingExpressions() {
393417
return groupByClauseExpressions;
@@ -442,6 +466,12 @@ public SqmQuerySpec<T> setGroupRestriction(Predicate... restrictions) {
442466
return this;
443467
}
444468

469+
@Override
470+
public SqmQuerySpec<T> setGroupRestriction(List<Predicate> restrictions) {
471+
havingClausePredicate = nodeBuilder().wrap( restrictions );
472+
return this;
473+
}
474+
445475
@Override
446476
public SqmQuerySpec<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications) {
447477
super.setSortSpecifications( sortSpecifications );

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

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.hibernate.query.sqm.tree.expression.ValueBindJpaCriteriaParameter;
2929
import org.hibernate.query.sqm.tree.expression.SqmParameter;
3030
import org.hibernate.query.sqm.tree.from.SqmFromClause;
31-
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
3231
import org.hibernate.query.sqm.tree.from.SqmRoot;
3332

3433
import jakarta.persistence.Tuple;
@@ -43,7 +42,6 @@
4342
import static java.util.Collections.emptySet;
4443
import static java.util.Collections.unmodifiableList;
4544
import static java.util.Collections.unmodifiableSet;
46-
import static org.hibernate.query.sqm.spi.SqmCreationHelper.combinePredicates;
4745
import static org.hibernate.query.sqm.SqmQuerySource.CRITERIA;
4846
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;
4947
import static org.hibernate.query.sqm.tree.jpa.ParameterCollector.collectParameters;
@@ -298,7 +296,8 @@ protected <X> JpaCteCriteria<X> withInternal(
298296

299297
@Override
300298
public SqmSelectStatement<T> distinct(boolean distinct) {
301-
return (SqmSelectStatement<T>) super.distinct( distinct );
299+
super.distinct( distinct );
300+
return this;
302301
}
303302

304303
@Override
@@ -319,21 +318,6 @@ public <U> SqmSubQuery<U> subquery(EntityType<U> type) {
319318
return new SqmSubQuery<>( this, type, nodeBuilder() );
320319
}
321320

322-
@Override
323-
public SqmSelectStatement<T> where(List<Predicate> restrictions) {
324-
//noinspection rawtypes,unchecked
325-
getQuerySpec().getWhereClause().applyPredicates( (List) restrictions );
326-
return this;
327-
}
328-
329-
@Override
330-
public SqmSelectStatement<T> having(List<Predicate> restrictions) {
331-
//noinspection unchecked,rawtypes
332-
final SqmPredicate combined = combinePredicates( getQuerySpec().getHavingClausePredicate(), (List) restrictions );
333-
getQuerySpec().setHavingClausePredicate( combined );
334-
return this;
335-
}
336-
337321
@Override
338322
@SuppressWarnings("unchecked")
339323
public SqmSelectStatement<T> select(Selection<? extends T> selection) {
@@ -424,32 +408,50 @@ public <U> SqmSubQuery<U> subquery(Class<U> type) {
424408

425409
@Override
426410
public SqmSelectStatement<T> where(Expression<Boolean> restriction) {
427-
return (SqmSelectStatement<T>) super.where( restriction );
411+
super.where( restriction );
412+
return this;
428413
}
429414

430415
@Override
431416
public SqmSelectStatement<T> where(Predicate... restrictions) {
432-
return (SqmSelectStatement<T>) super.where( restrictions );
417+
super.where( restrictions );
418+
return this;
419+
}
420+
421+
@Override
422+
public SqmSelectStatement<T> where(List<Predicate> restrictions) {
423+
super.where( restrictions );
424+
return this;
433425
}
434426

435427
@Override
436428
public SqmSelectStatement<T> groupBy(Expression<?>... expressions) {
437-
return (SqmSelectStatement<T>) super.groupBy( expressions );
429+
super.groupBy( expressions );
430+
return this;
438431
}
439432

440433
@Override
441434
public SqmSelectStatement<T> groupBy(List<Expression<?>> grouping) {
442-
return (SqmSelectStatement<T>) super.groupBy( grouping );
435+
super.groupBy( grouping );
436+
return this;
443437
}
444438

445439
@Override
446440
public SqmSelectStatement<T> having(Expression<Boolean> booleanExpression) {
447-
return (SqmSelectStatement<T>) super.having( booleanExpression );
441+
super.having( booleanExpression );
442+
return this;
448443
}
449444

450445
@Override
451446
public SqmSelectStatement<T> having(Predicate... predicates) {
452-
return (SqmSelectStatement<T>) super.having( predicates );
447+
super.having( predicates );
448+
return this;
449+
}
450+
451+
@Override
452+
public SqmSelectStatement<T> having(List<Predicate> restrictions) {
453+
super.having( restrictions );
454+
return this;
453455
}
454456

455457
@Override

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

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -345,37 +345,56 @@ public List<Selection<?>> getCompoundSelectionItems() {
345345

346346
@Override
347347
public SqmSubQuery<T> distinct(boolean distinct) {
348-
return (SqmSubQuery<T>) super.distinct( distinct );
348+
super.distinct( distinct );
349+
return this;
349350
}
350351

351352
@Override
352353
public SqmSubQuery<T> where(Expression<Boolean> restriction) {
353-
return (SqmSubQuery<T>) super.where( restriction );
354+
super.where( restriction );
355+
return this;
354356
}
355357

356358
@Override
357359
public SqmSubQuery<T> where(Predicate... restrictions) {
358-
return (SqmSubQuery<T>) super.where( restrictions );
360+
super.where( restrictions );
361+
return this;
362+
}
363+
364+
@Override
365+
public SqmSubQuery<T> where(List<Predicate> restrictions) {
366+
super.where( restrictions );
367+
return this;
359368
}
360369

361370
@Override
362371
public SqmSubQuery<T> groupBy(Expression<?>... expressions) {
363-
return (SqmSubQuery<T>) super.groupBy( expressions );
372+
super.groupBy( expressions );
373+
return this;
364374
}
365375

366376
@Override
367377
public SqmSubQuery<T> groupBy(List<Expression<?>> grouping) {
368-
return (SqmSubQuery<T>) super.groupBy( grouping );
378+
super.groupBy( grouping );
379+
return this;
369380
}
370381

371382
@Override
372383
public SqmSubQuery<T> having(Expression<Boolean> booleanExpression) {
373-
return (SqmSubQuery<T>) super.having( booleanExpression );
384+
super.having( booleanExpression );
385+
return this;
374386
}
375387

376388
@Override
377389
public SqmSubQuery<T> having(Predicate... predicates) {
378-
return (SqmSubQuery<T>) super.having( predicates );
390+
super.having( predicates );
391+
return this;
392+
}
393+
394+
@Override
395+
public SqmSubQuery<T> having(List<Predicate> restrictions) {
396+
super.having( restrictions );
397+
return this;
379398
}
380399

381400
@Override
@@ -719,21 +738,6 @@ public <U> Subquery<U> subquery(EntityType<U> type) {
719738
return new SqmSubQuery<>( this, type, nodeBuilder() );
720739
}
721740

722-
@Override
723-
public Subquery<T> where(List<Predicate> restrictions) {
724-
//noinspection rawtypes,unchecked
725-
getQuerySpec().getWhereClause().applyPredicates( (List) restrictions );
726-
return this;
727-
}
728-
729-
@Override
730-
public Subquery<T> having(List<Predicate> restrictions) {
731-
//noinspection unchecked,rawtypes
732-
final SqmPredicate combined = combinePredicates( getQuerySpec().getHavingClausePredicate(), (List) restrictions );
733-
getQuerySpec().setHavingClausePredicate( combined );
734-
return this;
735-
}
736-
737741
@Override
738742
public Set<ParameterExpression<?>> getParameters() {
739743
return Collections.emptySet();

0 commit comments

Comments
 (0)