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 <[email protected]>
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

Reply via email to