This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch 8.0.x-hibernate7-dev
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit ecd0263d1bd8624ee20c183d3f59dfa9e6c9aeb9
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Wed Mar 4 12:23:31 2026 -0600

    clean up HibernateHqlQuery
---
 .../hibernate/query/GrailsHibernateQueryUtils.java | 13 ++++-
 .../orm/hibernate/query/HibernateHqlQuery.java     | 66 +++++++++++++++-------
 .../grails/orm/hibernate/query/HibernateQuery.java |  5 +-
 .../hibernate/query/HibernateQueryExecutor.java    |  8 +--
 4 files changed, 63 insertions(+), 29 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java
index d0a342aba4..cc73b32ca9 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/GrailsHibernateQueryUtils.java
@@ -37,6 +37,7 @@ import org.grails.orm.hibernate.cfg.MappingCacheHolder;
 import org.hibernate.FetchMode;
 import org.hibernate.FlushMode;
 import org.hibernate.query.Query;
+import org.hibernate.query.QueryFlushMode;
 import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
 import org.hibernate.query.sqm.tree.expression.SqmFunction;
 import org.springframework.core.convert.ConversionService;
@@ -150,7 +151,7 @@ public class GrailsHibernateQueryUtils {
           
conversionService.convert(argMap.get(DynamicFinder.ARGUMENT_TIMEOUT), 
Integer.class));
     }
     if (argMap.containsKey(DynamicFinder.ARGUMENT_FLUSH_MODE)) {
-      
query.setHibernateFlushMode(convertFlushMode(argMap.get(DynamicFinder.ARGUMENT_FLUSH_MODE)));
+      
query.setQueryFlushMode(convertQueryFlushMode(argMap.get(DynamicFinder.ARGUMENT_FLUSH_MODE)));
     }
     if (argMap.containsKey(DynamicFinder.ARGUMENT_READ_ONLY)) {
       
query.setReadOnly(ClassUtils.getBooleanFromMap(DynamicFinder.ARGUMENT_READ_ONLY,
 argMap));
@@ -340,6 +341,16 @@ public class GrailsHibernateQueryUtils {
     }
   }
 
+  public static QueryFlushMode convertQueryFlushMode(Object object) {
+    FlushMode fm = convertFlushMode(object);
+    if (fm == null) return QueryFlushMode.DEFAULT;
+    return switch (fm) {
+      case ALWAYS -> QueryFlushMode.FLUSH;
+      case MANUAL, COMMIT -> QueryFlushMode.NO_FLUSH;
+      default -> QueryFlushMode.DEFAULT;
+    };
+  }
+
   /**
    * Retrieves the fetch mode for the specified instance; otherwise returns 
the default FetchMode.
    *
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java
index bdf3321ed7..f896a0adf2 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java
@@ -40,6 +40,7 @@ import org.grails.orm.hibernate.HibernateSession;
 import org.grails.orm.hibernate.exceptions.GrailsQueryException;
 import org.hibernate.FlushMode;
 import org.hibernate.SessionFactory;
+import org.hibernate.query.MutationQuery;
 import org.springframework.context.ApplicationEventPublisher;
 
 /**
@@ -51,12 +52,21 @@ import 
org.springframework.context.ApplicationEventPublisher;
 @SuppressWarnings("PMD.AvoidDuplicateLiterals")
 public class HibernateHqlQuery extends Query {
 
-  private org.hibernate.query.Query<?> query;
+  private final org.hibernate.query.Query<?> query;
+  private final org.hibernate.query.MutationQuery mutationQuery;
 
   public HibernateHqlQuery(
       Session session, PersistentEntity entity, org.hibernate.query.Query<?> 
query) {
     super(session, entity);
     this.query = query;
+    this.mutationQuery = null;
+  }
+
+  public HibernateHqlQuery(
+      Session session, PersistentEntity entity, 
org.hibernate.query.MutationQuery mutationQuery) {
+    super(session, entity);
+    this.query = null;
+    this.mutationQuery = mutationQuery;
   }
 
   @Override
@@ -82,8 +92,7 @@ public class HibernateHqlQuery extends Query {
    * Session-bound step — creates the {@link org.hibernate.query.Query} from 
an open {@link
    * org.hibernate.Session} and wraps it in a {@link HibernateHqlQuery}.
    */
-  @SuppressWarnings("unchecked")
-  public static HibernateHqlQuery buildQuery(
+  protected static HibernateHqlQuery buildQuery(
       org.hibernate.Session session,
       HibernateDatastore dataStore,
       SessionFactory sessionFactory,
@@ -92,8 +101,13 @@ public class HibernateHqlQuery extends Query {
     org.hibernate.query.Query<?> q;
     if (StringUtils.isEmpty(ctx.hql())) {
       q = session.createQuery("from " + ctx.targetClass().getName(), 
ctx.targetClass());
+      return new HibernateHqlQuery(new HibernateSession(dataStore, 
sessionFactory), entity, q);
     } else if (ctx.isUpdate()) {
-      q = session.createQuery(ctx.hql());
+      org.hibernate.query.MutationQuery mq = 
session.createMutationQuery(ctx.hql());
+      HibernateHqlQuery result =
+          new HibernateHqlQuery(new HibernateSession(dataStore, 
sessionFactory), entity, mq);
+      result.setFlushMode(session.getHibernateFlushMode());
+      return result;
     } else {
       q =
           ctx.isNative()
@@ -121,7 +135,9 @@ public class HibernateHqlQuery extends Query {
       GrailsHibernateTemplate template) {
     HibernateHqlQuery hqlQuery =
         template.execute(session -> buildQuery(session, dataStore, 
sessionFactory, entity, ctx));
-    template.applySettings(hqlQuery.getQuery());
+    if (hqlQuery.getQuery() != null) {
+      template.applySettings(hqlQuery.getQuery());
+    }
     hqlQuery.populateQuerySettings(
         MapUtils.isNotEmpty(args) ? new HashMap<>(args) : 
Collections.emptyMap());
     if (MapUtils.isNotEmpty(ctx.namedParams())) {
@@ -141,23 +157,31 @@ public class HibernateHqlQuery extends Query {
             : FlushModeType.COMMIT);
   }
 
-  @SuppressWarnings({"unchecked", "rawtypes"})
   public void populateQuerySettings(Map<?, ?> args) {
+    if (mutationQuery != null) {
+      ifPresent(args, DynamicFinder.ARGUMENT_TIMEOUT, v -> 
mutationQuery.setTimeout(toInt(v)));
+      ifPresent(
+          args,
+          DynamicFinder.ARGUMENT_FLUSH_MODE,
+          v -> 
mutationQuery.setQueryFlushMode(GrailsHibernateQueryUtils.convertQueryFlushMode(v)));
+      return;
+    }
+    if (query == null) return;
     ifPresent(args, DynamicFinder.ARGUMENT_MAX, v -> 
query.setMaxResults(toInt(v)));
     ifPresent(args, DynamicFinder.ARGUMENT_OFFSET, v -> 
query.setFirstResult(toInt(v)));
     ifPresent(args, DynamicFinder.ARGUMENT_CACHE, v -> 
query.setCacheable(toBool(v)));
     ifPresent(args, DynamicFinder.ARGUMENT_FETCH_SIZE, v -> 
query.setFetchSize(toInt(v)));
     ifPresent(args, DynamicFinder.ARGUMENT_TIMEOUT, v -> 
query.setTimeout(toInt(v)));
     ifPresent(args, DynamicFinder.ARGUMENT_READ_ONLY, v -> 
query.setReadOnly(toBool(v)));
-    if (args.containsKey(DynamicFinder.ARGUMENT_FLUSH_MODE)) {
-      Object v = args.get(DynamicFinder.ARGUMENT_FLUSH_MODE);
-      if (v instanceof FlushMode fm) query.setHibernateFlushMode(fm);
-    }
+    ifPresent(
+        args,
+        DynamicFinder.ARGUMENT_FLUSH_MODE,
+        v -> 
query.setQueryFlushMode(GrailsHibernateQueryUtils.convertQueryFlushMode(v)));
   }
 
-  @SuppressWarnings({"unchecked", "rawtypes"})
   public void populateQueryWithNamedArguments(Map<?, ?> namedArgs) {
     if (namedArgs == null) return;
+    org.hibernate.query.CommonQueryContract target = mutationQuery != null ? 
mutationQuery : query;
     namedArgs.forEach(
         (key, value) -> {
           if (!(key instanceof CharSequence)) {
@@ -165,27 +189,27 @@ public class HibernateHqlQuery extends Query {
           }
           String name = key.toString();
           if (value == null) {
-            query.setParameter(name, null);
-          } else if (value instanceof Collection<?> col) {
+            target.setParameter(name, null);
+          } else if (mutationQuery == null && value instanceof Collection<?> 
col) {
             query.setParameterList(name, col);
-          } else if (value.getClass().isArray()) {
+          } else if (mutationQuery == null && value.getClass().isArray()) {
             query.setParameterList(name, (Object[]) value);
           } else if (value instanceof CharSequence cs) {
-            query.setParameter(name, cs.toString(), String.class);
+            target.setParameter(name, cs.toString(), String.class);
           } else {
-            query.setParameter(name, value);
+            target.setParameter(name, value);
           }
         });
   }
 
-  @SuppressWarnings({"unchecked", "rawtypes"})
   public void populateQueryWithIndexedArguments(List<?> params) {
     if (params == null) return;
+    org.hibernate.query.CommonQueryContract target = mutationQuery != null ? 
mutationQuery : query;
     for (int i = 0; i < params.size(); i++) {
       Object val = params.get(i);
-      if (val instanceof CharSequence cs) query.setParameter(i + 1, 
cs.toString(), String.class);
-      else if (val != null) query.setParameter(i + 1, val);
-      else query.setParameter(i + 1, null);
+      if (val instanceof CharSequence cs) target.setParameter(i + 1, 
cs.toString(), String.class);
+      else if (val != null) target.setParameter(i + 1, val);
+      else target.setParameter(i + 1, null);
     }
   }
 
@@ -194,7 +218,7 @@ public class HibernateHqlQuery extends Query {
   }
 
   public int executeUpdate() {
-    return query.executeUpdate();
+    return mutationQuery != null ? mutationQuery.executeUpdate() : 
query.executeUpdate();
   }
 
   // ─── Private utilities ────────────────────────────────────────────────────
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
index bef86d7118..b8dd55d7bc 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
@@ -39,6 +39,7 @@ import org.grails.orm.hibernate.GrailsHibernateTemplate;
 import org.grails.orm.hibernate.IHibernateTemplate;
 import org.grails.orm.hibernate.proxy.HibernateProxyHandler;
 import org.hibernate.FlushMode;
+import org.hibernate.query.QueryFlushMode;
 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.query.criteria.HibernateCriteriaBuilder;
@@ -69,7 +70,7 @@ public class HibernateQuery extends Query {
 
   private Integer fetchSize;
   private Integer timeout;
-  private FlushMode flushMode;
+  private QueryFlushMode flushMode;
   private Boolean readOnly;
 
   public HibernateQuery(HibernateSession session, PersistentEntity entity) {
@@ -475,7 +476,7 @@ public class HibernateQuery extends Query {
   }
 
   public void setHibernateFlushMode(FlushMode flushMode) {
-    this.flushMode = flushMode;
+    this.flushMode = 
GrailsHibernateQueryUtils.convertQueryFlushMode(flushMode);
   }
 
   public void setReadOnly(Boolean readOnly) {
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 90bd13ae51..eeff4643f8 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
@@ -22,7 +22,7 @@ import jakarta.persistence.LockModeType;
 import java.util.List;
 import java.util.Optional;
 import org.grails.datastore.mapping.proxy.ProxyHandler;
-import org.hibernate.FlushMode;
+import org.hibernate.query.QueryFlushMode;
 import org.hibernate.NonUniqueResultException;
 import org.hibernate.Session;
 import org.hibernate.query.Query;
@@ -35,7 +35,7 @@ public record HibernateQueryExecutor(
     Boolean queryCache,
     Integer fetchSize,
     Integer timeout,
-    FlushMode flushMode,
+    QueryFlushMode flushMode,
     Boolean readOnly,
     ProxyHandler proxyHandler) {
 
@@ -71,9 +71,7 @@ public record HibernateQueryExecutor(
     Optional.ofNullable(lockResult).ifPresent(query::setLockMode);
     Optional.ofNullable(fetchSize).filter(v -> v > 
0).ifPresent(query::setFetchSize);
     Optional.ofNullable(timeout).filter(v -> v > 
0).ifPresent(query::setTimeout);
-    Optional.ofNullable(flushMode)
-        .map(mode -> mode.toJpaFlushMode())
-        .ifPresent(query::setFlushMode);
+    Optional.ofNullable(flushMode).ifPresent(query::setQueryFlushMode);
     Optional.ofNullable(readOnly).ifPresent(query::setReadOnly);
     return query;
   }

Reply via email to