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 4bc5c19e7544b72aa164c5aec23b9beb6111ff1e
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Thu Mar 5 16:18:32 2026 -0600

    hibernate7: clean up GrailsHibernateTemplate
---
 .../orm/hibernate/GrailsHibernateTemplate.java     | 124 +++++----------------
 1 file changed, 30 insertions(+), 94 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
index 41abd6a36b..c75a101bb5 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
@@ -23,17 +23,15 @@ import jakarta.persistence.LockModeType;
 import jakarta.persistence.PersistenceException;
 import jakarta.persistence.criteria.CriteriaBuilder;
 import jakarta.persistence.criteria.CriteriaQuery;
-import jakarta.persistence.criteria.Root;
 import java.io.Serializable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
+
 import javax.sql.DataSource;
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.hibernate.*;
@@ -96,10 +94,13 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         ((SessionFactoryImplementor) sessionFactory)
             .getServiceRegistry()
             .getService(ConnectionProvider.class);
-    this.dataSource = connectionProvider.unwrap(DataSource.class);
+    this.dataSource = connectionProvider != null ? 
connectionProvider.unwrap(DataSource.class) : null;
     if (this.dataSource != null) {
       if (this.dataSource instanceof TransactionAwareDataSourceProxy) {
-        this.dataSource = ((TransactionAwareDataSourceProxy) 
this.dataSource).getTargetDataSource();
+        DataSource target = ((TransactionAwareDataSourceProxy) 
this.dataSource).getTargetDataSource();
+        if (target != null) {
+          this.dataSource = target;
+        }
       }
       jdbcExceptionTranslator = new 
SQLErrorCodeSQLExceptionTranslator(this.dataSource);
     } else {
@@ -134,12 +135,12 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
 
   /** Maps a Hibernate {@link FlushMode} to one of the {@code FLUSH_*} 
constants of this class. */
   static int hibernateFlushModeToConstant(FlushMode mode) {
-    switch (mode) {
-      case MANUAL: return FLUSH_NEVER;
-      case COMMIT: return FLUSH_COMMIT;
-      case ALWAYS: return FLUSH_ALWAYS;
-      default: return FLUSH_AUTO;
-    }
+      return switch (mode) {
+          case MANUAL -> FLUSH_NEVER;
+          case COMMIT -> FLUSH_COMMIT;
+          case ALWAYS -> FLUSH_ALWAYS;
+          default -> FLUSH_AUTO;
+      };
   }
 
   @Override
@@ -188,7 +189,7 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
       sessionHolder = new SessionHolder(newSession);
       TransactionSynchronizationManager.bindResource(sessionFactory, 
sessionHolder);
 
-      return execute(callable::call);
+      return callable.call(newSession);
     } finally {
       try {
         // if an active synchronization was registered during the life time of 
the new session clear
@@ -259,7 +260,7 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
   }
 
   @Override
-  public void applySettings(org.hibernate.query.Query query) {
+  public void applySettings(org.hibernate.query.Query<?> query) {
     if (exposeNativeSession) {
       prepareQuery(query);
     }
@@ -348,10 +349,7 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
       }
       throw ex;
     } catch (SQLException ex) {
-      throw jdbcExceptionTranslator.translate("Hibernate-related JDBC 
operation", null, ex);
-    } catch (RuntimeException ex) {
-      // Callback code threw application exception...
-      throw ex;
+      throw 
Objects.requireNonNull(jdbcExceptionTranslator.translate("Hibernate-related 
JDBC operation", null, ex));
     } finally {
       if (existingTransaction) {
         LOG.debug("Not closing pre-bound Hibernate Session after 
HibernateTemplate");
@@ -403,7 +401,7 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         Proxy.newProxyInstance(
             Thread.currentThread().getContextClassLoader(),
             sessionIfcs,
-            new CloseSuppressingInvocationHandler(session));
+            new CloseSuppressingInvocationHandler(session, this));
   }
 
   @Deprecated(since = "7.0", forRemoval = true)
@@ -425,14 +423,6 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         true);
   }
 
-  public void flush(final Object entity) throws DataAccessException {
-    doExecute(
-        session -> {
-          session.flush();
-          return null;
-        },
-        true);
-  }
 
   public <T> T load(final Class<T> entityClass, final Serializable id) throws 
DataAccessException {
     return doExecute(session -> session.getReference(entityClass, id), true);
@@ -448,7 +438,7 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         session -> {
           final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
           final CriteriaQuery<T> query = 
criteriaBuilder.createQuery(entityClass);
-          final Root<T> root = query.from(entityClass);
+          query.from(entityClass);
           final Query<T> jpaQuery = session.createQuery(query);
           prepareCriteria(jpaQuery);
           return jpaQuery.getResultList();
@@ -508,7 +498,11 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
    *
    * @param query the Query object to prepare
    */
-  protected void prepareQuery(org.hibernate.query.Query query) {
+  void prepareQuery(org.hibernate.query.Query<?> query) {
+    internalQuery(query);
+  }
+
+  private void internalQuery(Query<?> query) {
     if (cacheQueries) {
       query.setCacheable(true);
     }
@@ -527,72 +521,13 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
    *
    * @param jpaQuery the Query object to prepare
    */
-  protected <T> void prepareCriteria(Query<T> jpaQuery) {
-    if (cacheQueries) {
-      jpaQuery.setCacheable(true);
-    }
-    if (shouldPassReadOnlyToHibernate()) {
-      jpaQuery.setReadOnly(true);
-    }
-    SessionHolder sessionHolder =
-        (SessionHolder) 
TransactionSynchronizationManager.getResource(sessionFactory);
-    if (sessionHolder != null && sessionHolder.hasTimeout()) {
-      jpaQuery.setTimeout(sessionHolder.getTimeToLiveInSeconds());
-    }
-  }
-
-  /**
-   * Invocation handler that suppresses close calls on Hibernate Sessions. 
Also prepares returned
-   * Query and Criteria objects.
-   *
-   * @see org.hibernate.Session#close
-   */
-  protected class CloseSuppressingInvocationHandler implements 
InvocationHandler {
-
-    protected final Session target;
-
-    protected CloseSuppressingInvocationHandler(Session target) {
-      this.target = target;
-    }
-
-    public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
-      // Invocation on Session interface coming in...
-
-      if (method.getName().equals("equals")) {
-        // Only consider equal when proxies are identical.
-        return (proxy == args[0]);
-      }
-      if (method.getName().equals("hashCode")) {
-        // Use hashCode of Session proxy.
-        return System.identityHashCode(proxy);
-      }
-      if (method.getName().equals("close")) {
-        // Handle close method: suppress, not valid.
-        return null;
-      }
-
-      // Invoke method on target Session.
-      try {
-        Object retVal = method.invoke(target, args);
-
-        // If return value is a Query or Criteria, apply transaction timeout.
-        // Applies to createQuery, getNamedQuery, createCriteria.
-        if (retVal instanceof org.hibernate.query.Query) {
-          prepareQuery(((org.hibernate.query.Query) retVal));
-        }
-        if (retVal instanceof Query) {
-          prepareCriteria(((Query) retVal));
-        }
-
-        return retVal;
-      } catch (InvocationTargetException ex) {
-        throw ex.getTargetException();
-      }
-    }
+  <T> void prepareCriteria(Query<T> jpaQuery) {
+    internalQuery(jpaQuery);
   }
 
-  /**
-   * Never flush is a good strategy for read-only units of work. Hibernate 
will not track and look
+    /**
+    * Never flush is a good strategy for read-only units of work.
+ Hibernate will not track and look
    * for changes in this case, avoiding any overhead of modification detection.
    *
    * <p>In case of an existing Session, FLUSH_NEVER will turn the flush mode 
to NEVER for the scope
@@ -698,7 +633,8 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         session.setHibernateFlushMode(FlushMode.MANUAL);
       }
     } else if (getFlushMode() == FLUSH_EAGER) {
-      if (existingTransaction) {
+        //noinspection StatementWithEmptyBody
+        if (existingTransaction) {
         FlushMode previousFlushMode = session.getHibernateFlushMode();
         if (!previousFlushMode.equals(FlushMode.AUTO)) {
           session.setHibernateFlushMode(FlushMode.AUTO);

Reply via email to