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:55 UTC
(grails-core) 20/22: Bridge Hibernate 7 Tuple results to GORM Object arrays and unify query elements
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 a23119d812246bf4f94322e4ec2e6969a0b3eda9
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Fri Feb 20 19:31:00 2026 -0600
Bridge Hibernate 7 Tuple results to GORM Object arrays and unify query elements
---
.../grails/orm/hibernate/query/HibernateQueryExecutor.java | 3 ++-
.../grails/orm/hibernate/query/JpaCriteriaQueryCreator.java | 12 ++++++++----
.../org/grails/orm/hibernate/query/PredicateGenerator.java | 5 ++---
.../groovy/org/grails/datastore/mapping/query/Query.java | 9 +++++++--
4 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQueryExecutor.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQueryExecutor.java
index be1b6e1a64..034d133438 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQueryExecutor.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQueryExecutor.java
@@ -1,12 +1,12 @@
package org.grails.orm.hibernate.query;
import jakarta.persistence.LockModeType;
+import jakarta.persistence.Tuple;
import org.grails.datastore.mapping.proxy.ProxyHandler;
import org.hibernate.FlushMode;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Session;
import org.hibernate.query.Query;
-import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import java.util.List;
@@ -49,6 +49,7 @@ public record HibernateQueryExecutor(
private Query configureQuery(Session session, JpaCriteriaQuery jpaCq) {
var query = session.createQuery(jpaCq);
+ if (jakarta.persistence.Tuple.class.equals(jpaCq.getResultType())) { query.setTupleTransformer((payload, aliases) -> payload); }
Optional.ofNullable(offset).filter(v -> v > 0).ifPresent(query::setFirstResult);
Optional.ofNullable(queryCache).ifPresent( qc -> query.setHint("org.hibernate.cacheable", qc));
Optional.ofNullable(maxResults).filter(v -> v > 0).ifPresent(query::setMaxResults);
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaCriteriaQueryCreator.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaCriteriaQueryCreator.java
index 5bd8289e81..6b5d4a266b 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaCriteriaQueryCreator.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaCriteriaQueryCreator.java
@@ -2,6 +2,7 @@ package org.grails.orm.hibernate.query;
import grails.gorm.DetachedCriteria;
+import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.From;
@@ -69,7 +70,7 @@ public class JpaCriteriaQueryCreator {
private JpaCriteriaQuery<?> createCriteriaQuery(List<Query.Projection> projections) {
var cq = projections.stream()
.filter( it -> !(it instanceof Query.DistinctProjection || it instanceof Query.DistinctPropertyProjection))
- .toList().size() > 1 ? criteriaBuilder.createQuery(Object[].class) : criteriaBuilder.createQuery(Object.class);
+ .toList().size() > 1 ? criteriaBuilder.createTupleQuery() : criteriaBuilder.createQuery(Object.class);
projections.stream()
.filter( it -> it instanceof Query.DistinctProjection || it instanceof Query.DistinctPropertyProjection)
.findFirst()
@@ -84,12 +85,15 @@ public class JpaCriteriaQueryCreator {
.filter(Objects::nonNull)
.toList();
if (projectionExpressions.size() == 1) {
- cq.select((Selection<? extends T>) projectionExpressions.get(0));
+ JpaExpression<?> jpaExpression = projectionExpressions.get(0);
+ cq.select((Selection<? extends T>) jpaExpression);
} else if (projectionExpressions.size() > 1){
var selectionArray = projectionExpressions.toArray(new Selection<?>[0]);
- ((JpaCriteriaQuery<Object[]>)cq).select(criteriaBuilder.array(selectionArray));
+ CriteriaQuery<Tuple> tupleCriteriaQuery = (CriteriaQuery<Tuple>) cq;
+ tupleCriteriaQuery.select(criteriaBuilder.tuple(selectionArray));
} else {
- cq.select((Selection<? extends T>) tablesByName.getFullyQualifiedPath("root"));
+ Path<?> root = tablesByName.getFullyQualifiedPath("root");
+ cq.select((Selection<? extends T>) root);
}
}
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 20c22e5813..65de3a2246 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
@@ -34,14 +34,13 @@ import java.util.Optional;
import java.util.stream.Stream;
@Slf4j
-@SuppressWarnings({"unchecked", "rawtypes"})
public class PredicateGenerator {
private static final Logger log = LoggerFactory.getLogger(PredicateGenerator.class);
public Predicate[] getPredicates(HibernateCriteriaBuilder cb,
CriteriaQuery<?> criteriaQuery,
From<?, ?> root_,
- List criteriaList,
+ List<? extends Query.QueryElement> criteriaList,
JpaFromProvider fromsByProvider,
PersistentEntity entity) {
@@ -57,7 +56,7 @@ public class PredicateGenerator {
return list.toArray(new Predicate[0]);
}
- private Predicate handleCriterion(HibernateCriteriaBuilder cb, CriteriaQuery<?> criteriaQuery, From<?, ?> root, JpaFromProvider fromsByProvider, PersistentEntity entity, Object criterion) {
+ private Predicate handleCriterion(HibernateCriteriaBuilder cb, CriteriaQuery<?> criteriaQuery, From<?, ?> root, JpaFromProvider fromsByProvider, PersistentEntity entity, Query.QueryElement criterion) {
if (criterion instanceof Query.Junction junction) {
return handleJunction(cb, criteriaQuery, root, fromsByProvider, entity, junction);
} else if (criterion instanceof Query.DistinctProjection) {
diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/query/Query.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/query/Query.java
index dc83ea6e19..b5a9df352d 100644
--- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/query/Query.java
+++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/query/Query.java
@@ -751,7 +751,12 @@ public abstract class Query implements Cloneable {
/**
* Represents a criterion to be used in a criteria query
*/
- public static interface Criterion {}
+ /**
+ * Common interface for all query elements
+ */
+ public static interface QueryElement {}
+
+ public static interface Criterion extends QueryElement {}
/**
* The ordering of results.
@@ -1395,7 +1400,7 @@ public abstract class Query implements Cloneable {
/**
* A projection
*/
- public static class Projection {}
+ public static class Projection implements QueryElement {}
/**
* A projection used to obtain the identifier of an object