You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/02/21 17:21:41 UTC
(grails-core) 06/22: Implement comprehensive single-level criteria coverage in PredicateGeneratorSpec
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch 8.0.x-hibernate7
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit ef7b9cf5b304480a23e75f65c0ffe6c7810a518d
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Fri Feb 20 09:09:13 2026 -0600
Implement comprehensive single-level criteria coverage in PredicateGeneratorSpec
---
.../orm/hibernate/query/PredicateGenerator.java | 26 +-
.../hibernatequery/PredicateGeneratorSpec.groovy | 359 +++++++++++++++++++++
2 files changed, 372 insertions(+), 13 deletions(-)
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
index 7e11030368..80cf7fdd91 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
@@ -49,14 +49,14 @@ public class PredicateGenerator {
public Predicate[] getPredicates(HibernateCriteriaBuilder cb,
CriteriaQuery criteriaQuery,
From root_,
- List<Query.Criterion> criteriaList, JpaFromProvider fromsByProvider, PersistentEntity entity) {
+ List criteriaList, JpaFromProvider fromsByProvider, PersistentEntity entity) {
List<Predicate> list = criteriaList.stream().
- map(criterion -> {
+ map((Object criterion) -> {
if (criterion instanceof Query.Junction junction) {
var criterionList = junction.getCriteria();
- var predicates = this.getPredicates(cb, criteriaQuery, root_, criterionList, fromsByProvider, entity);
+ var predicates = (Predicate[])this.getPredicates(cb, criteriaQuery, root_, (List)criterionList, fromsByProvider, entity);
if (junction instanceof Query.Disjunction) {
return cb.or(predicates);
} else if (junction instanceof Query.Conjunction) {
@@ -76,7 +76,7 @@ public class PredicateGenerator {
List<Query.Criterion> criterionList = c.getCriteria();
JpaFromProvider childTablesByName = (JpaFromProvider) fromsByProvider.clone();
childTablesByName.put("root", child);
- return cb.and(this.getPredicates(cb, criteriaQuery, child, criterionList, childTablesByName, entity));
+ return cb.and((Predicate[])this.getPredicates(cb, criteriaQuery, child, (List)criterionList, childTablesByName, entity));
} else if (criterion instanceof Query.PropertyCriterion pc) {
var fullyQualifiedPath = fromsByProvider.getFullyQualifiedPath(pc.getProperty());
if (criterion instanceof Query.Equals c) {
@@ -122,10 +122,10 @@ public class PredicateGenerator {
} else if (criterion instanceof Query.Like c) {
return cb.like(fullyQualifiedPath, c.getValue().toString());
} else if (criterion instanceof Query.In c) {
- var queryableCriteria = getQueryableCriteriaFromInCriteria(criterion);
+ var queryableCriteria = getQueryableCriteriaFromInCriteria((Query.Criterion)criterion);
if (Objects.nonNull(queryableCriteria)) {
- CriteriaBuilder.In value = getQueryableCriteriaValue(cb, criteriaQuery, fromsByProvider, entity, (Query.PropertyNameCriterion) criterion, queryableCriteria);
+ CriteriaBuilder.In value = getQueryableCriteriaValue(cb, criteriaQuery, fromsByProvider, entity, (Query.PropertyNameCriterion)criterion, queryableCriteria);
return value;
} else if (!c.getValues().isEmpty()) {
boolean areGormEntities = c.getValues().stream().allMatch(GormEntity.class::isInstance);
@@ -138,9 +138,9 @@ public class PredicateGenerator {
return cb.in(fullyQualifiedPath, c.getValues());
}
} else if (criterion instanceof Query.NotIn c) {
- var queryableCriteria = getQueryableCriteriaFromInCriteria(criterion);
+ var queryableCriteria = getQueryableCriteriaFromInCriteria((Query.Criterion)criterion);
if (Objects.nonNull(queryableCriteria)) {
- CriteriaBuilder.In value = getQueryableCriteriaValue(cb, criteriaQuery, fromsByProvider, entity, (Query.PropertyNameCriterion) criterion, queryableCriteria);
+ CriteriaBuilder.In value = getQueryableCriteriaValue(cb, criteriaQuery, fromsByProvider, entity, (Query.PropertyNameCriterion)criterion, queryableCriteria);
return cb.not(value);
} else if (Objects.nonNull(c.getSubquery())
&& !c.getSubquery().getProjections().isEmpty()
@@ -152,7 +152,7 @@ public class PredicateGenerator {
Query.PropertyProjection projection = (Query.PropertyProjection) c.getSubquery().getProjections().get(0);
boolean distinct = projection instanceof Query.DistinctPropertyProjection;
JpaFromProvider newMap2 = (JpaFromProvider) fromsByProvider.clone();
- Predicate[] predicates2 = this.getPredicates(cb, criteriaQuery, from2, subCriteria2, newMap2, entity);
+ Predicate[] predicates2 = (Predicate[])this.getPredicates(cb, criteriaQuery, from2, (List)subCriteria2, newMap2, entity);
subquery2.select(from2.get(projection.getPropertyName())).distinct(distinct).where(cb.and(predicates2));
return cb.not(cb.in(fullyQualifiedPath).value(subquery2));
} else if ( Objects.nonNull(c.getSubquery())
@@ -163,7 +163,7 @@ public class PredicateGenerator {
Root from2 = subquery2.from(c.getValue().getPersistentEntity().getJavaClass());
List subCriteria2 = c.getValue().getCriteria();
JpaFromProvider newMap2 = (JpaFromProvider) fromsByProvider.clone();
- Predicate[] predicates2 = this.getPredicates(cb, criteriaQuery, from2, subCriteria2, newMap2, entity);
+ Predicate[] predicates2 = (Predicate[])this.getPredicates(cb, criteriaQuery, from2, (List)subCriteria2, newMap2, entity);
subquery2.select(from2).where(cb.and(predicates2));
return cb.not(cb.in(root_.get("id")).value(subquery2));
} else {
@@ -176,7 +176,7 @@ public class PredicateGenerator {
List subCriteria = c.getValue().getCriteria();
JpaFromProvider newMap = (JpaFromProvider) fromsByProvider.clone();
newMap.put("root", from);
- Predicate[] predicates = this.getPredicates(cb, criteriaQuery, from, subCriteria, newMap, entity);
+ Predicate[] predicates = (Predicate[])this.getPredicates(cb, criteriaQuery, from, (List)subCriteria, newMap, entity);
if (c instanceof Query.GreaterThanEqualsAll sc) {
subquery.select(cb.max(from.get(c.getProperty()))).where(cb.and(predicates));
return cb.greaterThanOrEqualTo(fromsByProvider.getFullyQualifiedPath(sc.getProperty()), subquery);
@@ -236,7 +236,7 @@ public class PredicateGenerator {
JpaFromProvider newMap = (JpaFromProvider) fromsByProvider.clone();
newMap.put("root", subRoot);
- var predicates = this.getPredicates(cb, criteriaQuery, subRoot, c.getSubquery().getCriteria(), newMap, entity);
+ var predicates = (Predicate[])this.getPredicates(cb, criteriaQuery, subRoot, (List)c.getSubquery().getCriteria(), newMap, entity);
var existsPredicate = getExistsPredicate(cb, root_, childPersistentEntity, subRoot);
Predicate[] allPredicates = Stream.concat(
@@ -255,7 +255,7 @@ public class PredicateGenerator {
JpaFromProvider newMap = (JpaFromProvider) fromsByProvider.clone();
newMap.put("root", subRoot);
- var predicates = this.getPredicates(cb, criteriaQuery, subRoot, c.getSubquery().getCriteria(), newMap, entity);
+ var predicates = (Predicate[])this.getPredicates(cb, criteriaQuery, subRoot, (List)c.getSubquery().getCriteria(), newMap, entity);
var existsPredicate = getExistsPredicate(cb, root_, childPersistentEntity, subRoot);
Predicate[] allPredicates = Stream.concat(
diff --git a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/hibernatequery/PredicateGeneratorSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/hibernatequery/PredicateGeneratorSpec.groovy
new file mode 100644
index 0000000000..de19560c88
--- /dev/null
+++ b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/specs/hibernatequery/PredicateGeneratorSpec.groovy
@@ -0,0 +1,359 @@
+package grails.gorm.specs.hibernatequery
+
+import grails.gorm.DetachedCriteria
+import grails.gorm.specs.HibernateGormDatastoreSpec
+import jakarta.persistence.criteria.CriteriaQuery
+import jakarta.persistence.criteria.Root
+import org.apache.grails.data.testing.tck.domains.Person
+import org.apache.grails.data.testing.tck.domains.Pet
+import org.apache.grails.data.testing.tck.domains.Face
+import org.grails.datastore.mapping.model.PersistentEntity
+import org.grails.datastore.mapping.query.Query
+import org.grails.orm.hibernate.query.JpaFromProvider
+import org.grails.orm.hibernate.query.PredicateGenerator
+import org.hibernate.query.criteria.HibernateCriteriaBuilder
+
+class PredicateGeneratorSpec extends HibernateGormDatastoreSpec {
+
+ PredicateGenerator predicateGenerator
+ HibernateCriteriaBuilder cb
+ CriteriaQuery<Person> query
+ Root<Person> root
+ JpaFromProvider fromProvider
+ PersistentEntity personEntity
+
+ def setup() {
+ predicateGenerator = new PredicateGenerator()
+ cb = sessionFactory.getCriteriaBuilder()
+ query = cb.createQuery(Person)
+ root = query.from(Person)
+ personEntity = manager.hibernateDatastore.getMappingContext().getPersistentEntity(Person.typeName)
+ fromProvider = new JpaFromProvider(new DetachedCriteria(Person), query, root)
+ }
+
+ def setupSpec() {
+ manager.addAllDomainClasses([Person, Pet, Face])
+ }
+
+ def "test getPredicates with Equals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.Equals("firstName", "Bob")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with NotEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.NotEquals("firstName", "Bob")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with IdEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.IdEquals(1L)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with GreaterThan criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.GreaterThan("age", 20)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with GreaterThanEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.GreaterThanEquals("age", 20)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with LessThan criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.LessThan("age", 20)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with LessThanEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.LessThanEquals("age", 20)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeEquals("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeNotEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeNotEquals("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeGreaterThan criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeGreaterThan("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeGreaterThanEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeGreaterThanEquals("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeLessThan criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeLessThan("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with SizeLessThanEquals criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.SizeLessThanEquals("pets", 1)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with Between criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.Between("age", 18, 30)]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with ILike criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.ILike("firstName", "B%")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with RLike criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.RLike("firstName", "B.*")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with Like criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.Like("firstName", "B%")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with In criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.In("firstName", ["Bob", "Fred"])]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with NotIn criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.NotIn("firstName", new DetachedCriteria(Person).eq("firstName", "Bob").property("firstName"))]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with IsNull criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.IsNull("firstName")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with IsNotNull criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.IsNotNull("firstName")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with IsEmpty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.IsEmpty("pets")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with IsNotEmpty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.IsNotEmpty("pets")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with EqualsProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.EqualsProperty("firstName", "lastName")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with NotEqualsProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.NotEqualsProperty("firstName", "lastName")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with LessThanEqualsProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.LessThanEqualsProperty("age", "age")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with LessThanProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.LessThanProperty("age", "age")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with GreaterThanEqualsProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.GreaterThanEqualsProperty("age", "age")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with GreaterThanProperty criterion"() {
+ given:
+ List<Query.Criterion> criteria = [new Query.GreaterThanProperty("age", "age")]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with DistinctProjection criterion"() {
+ given:
+ def distinct = new Query.DistinctProjection()
+ def criteriaList = [distinct]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteriaList, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with Conjunction"() {
+ given:
+ var conjunction = new Query.Conjunction()
+ conjunction.add(new Query.Equals("firstName", "Bob"))
+ conjunction.add(new Query.GreaterThan("age", 20))
+ List<Query.Criterion> criteria = [conjunction]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with Disjunction"() {
+ given:
+ var disjunction = new Query.Disjunction()
+ disjunction.add(new Query.Equals("firstName", "Bob"))
+ disjunction.add(new Query.Equals("firstName", "Fred"))
+ List<Query.Criterion> criteria = [disjunction]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with Negation"() {
+ given:
+ var negation = new Query.Negation()
+ negation.add(new Query.Equals("firstName", "Bob"))
+ List<Query.Criterion> criteria = [negation]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ def "test getPredicates with DetachedAssociationCriteria"() {
+ given:
+ var association = personEntity.getPropertyByName("pets")
+ var associationCriteria = new org.grails.datastore.gorm.query.criteria.DetachedAssociationCriteria(Pet, association, "pets")
+ associationCriteria.eq("name", "Lucky")
+ List criteria = [associationCriteria]
+ when:
+ def predicates = predicateGenerator.getPredicates(cb, query, root, (List<Query.Criterion>)criteria, fromProvider, personEntity)
+ then:
+ predicates.length == 1
+ }
+
+ private jakarta.persistence.criteria.Predicate[] callGetPredicatesUntyped(List criteria) {
+ return predicateGenerator.getPredicates(cb, query, root, criteria, fromProvider, personEntity)
+ }
+}