Skip to content

Commit 867e3a8

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

File tree

8 files changed

+127
-63
lines changed

8 files changed

+127
-63
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
SqmExpression<?> fk(Path<?> 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
@@ -598,6 +598,19 @@ public final SqmPredicate wrap(Expression<Boolean>... expressions) {
598598
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
599599
}
600600

601+
@Override
602+
public SqmPredicate wrap(List<? extends Expression<Boolean>> restrictions) {
603+
if ( restrictions.size() == 1 ) {
604+
return wrap( restrictions.get( 0 ) );
605+
}
606+
607+
final List<SqmPredicate> predicates = new ArrayList<>( restrictions.size() );
608+
for ( Expression<Boolean> expression : restrictions ) {
609+
predicates.add( wrap( expression ) );
610+
}
611+
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
612+
}
613+
601614
@Override @SuppressWarnings("unchecked")
602615
public <T extends HibernateCriteriaBuilder> T unwrap(Class<T> clazz) {
603616
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
@@ -46,12 +46,10 @@ public void setPredicate(SqmPredicate predicate) {
4646

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

5755
@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
@@ -377,6 +377,12 @@ public SqmSelectQuery<T> where(Predicate... restrictions) {
377377
return this;
378378
}
379379

380+
@Override
381+
public SqmSelectQuery<T> where(List<Predicate> restrictions) {
382+
getQuerySpec().setRestriction( restrictions );
383+
return this;
384+
}
385+
380386

381387
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382388
// Grouping
@@ -388,7 +394,7 @@ public List<Expression<?>> getGroupList() {
388394

389395
@Override
390396
public SqmSelectQuery<T> groupBy(Expression<?>... expressions) {
391-
getQuerySpec().setGroupingExpressions( List.of( expressions ) );
397+
getQuerySpec().setGroupingExpressions( expressions );
392398
return this;
393399
}
394400

@@ -405,13 +411,19 @@ public SqmPredicate getGroupRestriction() {
405411

406412
@Override
407413
public SqmSelectQuery<T> having(Expression<Boolean> booleanExpression) {
408-
getQuerySpec().setGroupRestriction( nodeBuilder().wrap( booleanExpression ) );
414+
getQuerySpec().setGroupRestriction( booleanExpression );
409415
return this;
410416
}
411417

412418
@Override
413419
public SqmSelectQuery<T> having(Predicate... predicates) {
414-
getQuerySpec().setGroupRestriction( nodeBuilder().wrap( predicates ) );
420+
getQuerySpec().setGroupRestriction( predicates );
421+
return this;
422+
}
423+
424+
@Override
425+
public AbstractQuery<T> having(List<Predicate> restrictions) {
426+
getQuerySpec().setGroupRestriction( restrictions );
415427
return this;
416428
}
417429

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
@@ -26,7 +26,6 @@
2626
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
2727
import org.hibernate.query.sqm.tree.expression.SqmParameter;
2828
import org.hibernate.query.sqm.tree.from.SqmFromClause;
29-
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
3029
import org.hibernate.query.sqm.tree.from.SqmRoot;
3130

3231
import jakarta.persistence.Tuple;
@@ -41,7 +40,6 @@
4140
import static java.util.Collections.emptySet;
4241
import static java.util.Collections.unmodifiableList;
4342
import static java.util.Collections.unmodifiableSet;
44-
import static org.hibernate.query.sqm.spi.SqmCreationHelper.combinePredicates;
4543
import static org.hibernate.query.sqm.SqmQuerySource.CRITERIA;
4644
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;
4745
import static org.hibernate.query.sqm.tree.jpa.ParameterCollector.collectParameters;
@@ -291,7 +289,8 @@ protected <X> JpaCteCriteria<X> withInternal(
291289

292290
@Override
293291
public SqmSelectStatement<T> distinct(boolean distinct) {
294-
return (SqmSelectStatement<T>) super.distinct( distinct );
292+
super.distinct( distinct );
293+
return this;
295294
}
296295

297296
@Override
@@ -308,21 +307,6 @@ public <U> SqmSubQuery<U> subquery(EntityType<U> type) {
308307
return new SqmSubQuery<>( this, type, nodeBuilder() );
309308
}
310309

311-
@Override
312-
public SqmSelectStatement<T> where(List<Predicate> restrictions) {
313-
//noinspection rawtypes,unchecked
314-
getQuerySpec().getWhereClause().applyPredicates( (List) restrictions );
315-
return this;
316-
}
317-
318-
@Override
319-
public SqmSelectStatement<T> having(List<Predicate> restrictions) {
320-
final SqmPredicate combined =
321-
combinePredicates( getQuerySpec().getHavingClausePredicate(), restrictions );
322-
getQuerySpec().setHavingClausePredicate( combined );
323-
return this;
324-
}
325-
326310
@Override
327311
@SuppressWarnings("unchecked")
328312
public SqmSelectStatement<T> select(Selection<? extends T> selection) {
@@ -413,32 +397,50 @@ public <U> SqmSubQuery<U> subquery(Class<U> type) {
413397

414398
@Override
415399
public SqmSelectStatement<T> where(Expression<Boolean> restriction) {
416-
return (SqmSelectStatement<T>) super.where( restriction );
400+
super.where( restriction );
401+
return this;
417402
}
418403

419404
@Override
420405
public SqmSelectStatement<T> where(Predicate... restrictions) {
421-
return (SqmSelectStatement<T>) super.where( restrictions );
406+
super.where( restrictions );
407+
return this;
408+
}
409+
410+
@Override
411+
public SqmSelectStatement<T> where(List<Predicate> restrictions) {
412+
super.where( restrictions );
413+
return this;
422414
}
423415

424416
@Override
425417
public SqmSelectStatement<T> groupBy(Expression<?>... expressions) {
426-
return (SqmSelectStatement<T>) super.groupBy( expressions );
418+
super.groupBy( expressions );
419+
return this;
427420
}
428421

429422
@Override
430423
public SqmSelectStatement<T> groupBy(List<Expression<?>> grouping) {
431-
return (SqmSelectStatement<T>) super.groupBy( grouping );
424+
super.groupBy( grouping );
425+
return this;
432426
}
433427

434428
@Override
435429
public SqmSelectStatement<T> having(Expression<Boolean> booleanExpression) {
436-
return (SqmSelectStatement<T>) super.having( booleanExpression );
430+
super.having( booleanExpression );
431+
return this;
437432
}
438433

439434
@Override
440435
public SqmSelectStatement<T> having(Predicate... predicates) {
441-
return (SqmSelectStatement<T>) super.having( predicates );
436+
super.having( predicates );
437+
return this;
438+
}
439+
440+
@Override
441+
public SqmSelectStatement<T> having(List<Predicate> restrictions) {
442+
super.having( restrictions );
443+
return this;
442444
}
443445

444446
@Override

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

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
import jakarta.persistence.metamodel.EntityType;
7878

7979
import static java.util.Collections.emptySet;
80-
import static org.hibernate.query.sqm.spi.SqmCreationHelper.combinePredicates;
8180

8281
/**
8382
* @author Steve Ebersole
@@ -345,37 +344,56 @@ public List<Selection<?>> getCompoundSelectionItems() {
345344

346345
@Override
347346
public SqmSubQuery<T> distinct(boolean distinct) {
348-
return (SqmSubQuery<T>) super.distinct( distinct );
347+
super.distinct( distinct );
348+
return this;
349349
}
350350

351351
@Override
352352
public SqmSubQuery<T> where(Expression<Boolean> restriction) {
353-
return (SqmSubQuery<T>) super.where( restriction );
353+
super.where( restriction );
354+
return this;
354355
}
355356

356357
@Override
357358
public SqmSubQuery<T> where(Predicate... restrictions) {
358-
return (SqmSubQuery<T>) super.where( restrictions );
359+
super.where( restrictions );
360+
return this;
361+
}
362+
363+
@Override
364+
public SqmSubQuery<T> where(List<Predicate> restrictions) {
365+
super.where( restrictions );
366+
return this;
359367
}
360368

361369
@Override
362370
public SqmSubQuery<T> groupBy(Expression<?>... expressions) {
363-
return (SqmSubQuery<T>) super.groupBy( expressions );
371+
super.groupBy( expressions );
372+
return this;
364373
}
365374

366375
@Override
367376
public SqmSubQuery<T> groupBy(List<Expression<?>> grouping) {
368-
return (SqmSubQuery<T>) super.groupBy( grouping );
377+
super.groupBy( grouping );
378+
return this;
369379
}
370380

371381
@Override
372382
public SqmSubQuery<T> having(Expression<Boolean> booleanExpression) {
373-
return (SqmSubQuery<T>) super.having( booleanExpression );
383+
super.having( booleanExpression );
384+
return this;
374385
}
375386

376387
@Override
377388
public SqmSubQuery<T> having(Predicate... predicates) {
378-
return (SqmSubQuery<T>) super.having( predicates );
389+
super.having( predicates );
390+
return this;
391+
}
392+
393+
@Override
394+
public SqmSubQuery<T> having(List<Predicate> restrictions) {
395+
super.having( restrictions );
396+
return this;
379397
}
380398

381399
@Override
@@ -721,21 +739,6 @@ public <U> Subquery<U> subquery(EntityType<U> type) {
721739
return new SqmSubQuery<>( this, type, nodeBuilder() );
722740
}
723741

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

0 commit comments

Comments
 (0)