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/09/09 23:41:18 UTC

(grails-core) 07/14: Convert grails-data-hibernate7-spring-orm batch 1 to Groovy

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

borinquenkid pushed a commit to branch 9.0.x-java-to-groovy
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit 8cb1d488efec86a6268828266e627948e7b360fb
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Tue Sep 8 21:17:32 2026 -0500

    Convert grails-data-hibernate7-spring-orm batch 1 to Groovy
    
    Converts 14 of the 22 vendored Spring ORM support classes in
    org.grails.orm.hibernate.support.hibernate7 to @CompileStatic Groovy,
    preserving the upstream Spring copyright headers verbatim:
    HibernateCallback, HibernateJdbcException,
    HibernateObjectRetrievalFailureException,
    HibernateOptimisticLockingFailureException, HibernateQueryException,
    HibernateSystemException, SessionHolder, SpringJtaSessionContext,
    SpringFlushSynchronization, HibernateExceptionTranslator,
    ConfigurableJtaPlatform, SpringSessionContext,
    SpringSessionSynchronization and support.AsyncRequestInterceptor.
    
    Verified with codenarcMain/checkstyleMain on spring-orm and the full
    grails-data-hibernate7-core, grails-data-hibernate7 and
    grails-data-hibernate7-spring-boot test suites.
    
    Co-Authored-By: Claude Fable 5.1 <no...@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01E5dsQNQNLuSdFph84RRQdr
---
 ...latform.java => ConfigurableJtaPlatform.groovy} |  94 ++++++++--------
 ...rnateCallback.java => HibernateCallback.groovy} |  13 +--
 ...or.java => HibernateExceptionTranslator.groovy} |  55 +++++----
 ...xception.java => HibernateJdbcException.groovy} |  34 +++---
 ...ibernateObjectRetrievalFailureException.groovy} |  39 ++++---
 ...ernateOptimisticLockingFailureException.groovy} |  30 ++---
 ...ception.java => HibernateQueryException.groovy} |  26 ++---
 ...eption.java => HibernateSystemException.groovy} |  19 ++--
 .../{SessionHolder.java => SessionHolder.groovy}   |  59 +++++-----
 ...tion.java => SpringFlushSynchronization.groovy} |  33 +++---
 ...Context.java => SpringJtaSessionContext.groovy} |  30 ++---
 ...ionContext.java => SpringSessionContext.groovy} | 124 ++++++++++-----------
 ...on.java => SpringSessionSynchronization.groovy} | 109 +++++++++---------
 .../support/AsyncRequestInterceptor.groovy         | 123 ++++++++++++++++++++
 .../support/AsyncRequestInterceptor.java           | 123 --------------------
 15 files changed, 439 insertions(+), 472 deletions(-)

diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.groovy
similarity index 50%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.groovy
index a01d1d29a9..0abea61c8e 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/ConfigurableJtaPlatform.groovy
@@ -13,23 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package org.grails.orm.hibernate.support.hibernate7;
-
-import jakarta.transaction.Status;
-import jakarta.transaction.Synchronization;
-import jakarta.transaction.SystemException;
-import jakarta.transaction.Transaction;
-import jakarta.transaction.TransactionManager;
-import jakarta.transaction.TransactionSynchronizationRegistry;
-import jakarta.transaction.UserTransaction;
-
-import org.hibernate.TransactionException;
-import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.transaction.jta.UserTransactionAdapter;
-import org.springframework.util.Assert;
+package org.grails.orm.hibernate.support.hibernate7
+
+import groovy.transform.CompileStatic
+import groovy.transform.PackageScope
+import jakarta.transaction.Status
+import jakarta.transaction.Synchronization
+import jakarta.transaction.SystemException
+import jakarta.transaction.Transaction
+import jakarta.transaction.TransactionManager
+import jakarta.transaction.TransactionSynchronizationRegistry
+import jakarta.transaction.UserTransaction
+import org.hibernate.TransactionException
+import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform
+import org.springframework.transaction.jta.UserTransactionAdapter
+import org.springframework.util.Assert
 
 /**
  * Implementation of Hibernate 5's JtaPlatform SPI, exposing passed-in {@link TransactionManager},
@@ -38,15 +36,16 @@ import org.springframework.util.Assert;
  * @author Juergen Hoeller
  * @since 4.2
  */
-@SuppressWarnings("serial")
+@CompileStatic
+@PackageScope
+@SuppressWarnings('serial')
 class ConfigurableJtaPlatform implements JtaPlatform {
 
-    private final TransactionManager transactionManager;
+    private final TransactionManager transactionManager
 
-    private final UserTransaction userTransaction;
+    private final UserTransaction userTransaction
 
-    @Nullable
-    private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
+    private final TransactionSynchronizationRegistry transactionSynchronizationRegistry
 
     /**
      * Create a new ConfigurableJtaPlatform instance with the given
@@ -55,57 +54,54 @@ class ConfigurableJtaPlatform implements JtaPlatform {
      * @param ut the JTA UserTransaction reference (optional)
      * @param tsr the JTA 1.1 TransactionSynchronizationRegistry (optional)
      */
-    public ConfigurableJtaPlatform(TransactionManager tm, @Nullable UserTransaction ut,
-            @Nullable TransactionSynchronizationRegistry tsr) {
-        Assert.notNull(tm, "TransactionManager reference must not be null");
-        this.transactionManager = tm;
-        this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm));
-        this.transactionSynchronizationRegistry = tsr;
+    ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut,
+                            TransactionSynchronizationRegistry tsr) {
+        Assert.notNull(tm, 'TransactionManager reference must not be null')
+        this.transactionManager = tm
+        this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm))
+        this.transactionSynchronizationRegistry = tsr
     }
 
     @Override
-    public TransactionManager retrieveTransactionManager() {
-        return this.transactionManager;
+    TransactionManager retrieveTransactionManager() {
+        return this.transactionManager
     }
 
     @Override
-    public UserTransaction retrieveUserTransaction() {
-        return this.userTransaction;
+    UserTransaction retrieveUserTransaction() {
+        return this.userTransaction
     }
 
     @Override
-    public Object getTransactionIdentifier(Transaction transaction) {
-        return transaction;
+    Object getTransactionIdentifier(Transaction transaction) {
+        return transaction
     }
 
     @Override
-    public boolean canRegisterSynchronization() {
+    boolean canRegisterSynchronization() {
         try {
-            return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE);
-        }
-        catch (SystemException ex) {
-            throw new TransactionException("Could not determine JTA transaction status", ex);
+            return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE)
+        } catch (SystemException ex) {
+            throw new TransactionException('Could not determine JTA transaction status', ex)
         }
     }
 
     @Override
-    public void registerSynchronization(Synchronization synchronization) {
+    void registerSynchronization(Synchronization synchronization) {
         if (this.transactionSynchronizationRegistry != null) {
-            this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization);
-        }
-        else {
+            this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization)
+        } else {
             try {
-                this.transactionManager.getTransaction().registerSynchronization(synchronization);
-            }
-            catch (Exception ex) {
-                throw new TransactionException("Could not access JTA Transaction to register synchronization", ex);
+                this.transactionManager.getTransaction().registerSynchronization(synchronization)
+            } catch (Exception ex) {
+                throw new TransactionException('Could not access JTA Transaction to register synchronization', ex)
             }
         }
     }
 
     @Override
-    public int getCurrentStatus() throws SystemException {
-        return this.transactionManager.getStatus();
+    int getCurrentStatus() throws SystemException {
+        return this.transactionManager.getStatus()
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.groovy
similarity index 86%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.groovy
index 3ddb30d0c0..11ba6f98a9 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateCallback.groovy
@@ -13,12 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.jspecify.annotations.Nullable;
+import org.hibernate.HibernateException
+import org.hibernate.Session
 
 /**
  * Callback interface for Hibernate code. To be used with {@link HibernateTemplate}'s
@@ -33,7 +31,7 @@ import org.jspecify.annotations.Nullable;
  * @see HibernateTransactionManager
  */
 @FunctionalInterface
-public interface HibernateCallback<T> {
+interface HibernateCallback<T> {
 
     /**
      * Gets called by {@code HibernateTemplate.execute} with an active
@@ -48,7 +46,6 @@ public interface HibernateCallback<T> {
      * @throws HibernateException if thrown by the Hibernate API
      * @see HibernateTemplate#execute
      */
-    @Nullable
-    T doInHibernate(Session session) throws HibernateException;
+    T doInHibernate(Session session) throws HibernateException
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.groovy
similarity index 70%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.groovy
index e67c3e3b56..228d7d48f6 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateExceptionTranslator.groovy
@@ -13,19 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import jakarta.persistence.PersistenceException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.support.PersistenceExceptionTranslator;
-import org.springframework.jdbc.support.SQLExceptionTranslator;
-import org.springframework.orm.jpa.EntityManagerFactoryUtils;
+import groovy.transform.CompileStatic
+import jakarta.persistence.PersistenceException
+import org.hibernate.HibernateException
+import org.hibernate.JDBCException
+import org.springframework.dao.DataAccessException
+import org.springframework.dao.support.PersistenceExceptionTranslator
+import org.springframework.jdbc.support.SQLExceptionTranslator
+import org.springframework.orm.jpa.EntityManagerFactoryUtils
 
 /**
  * {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException}
@@ -44,10 +41,10 @@ import org.springframework.orm.jpa.EntityManagerFactoryUtils;
  * @see SessionFactoryUtils#convertHibernateAccessException(HibernateException)
  * @see EntityManagerFactoryUtils#convertJpaAccessExceptionIfPossible(RuntimeException)
  */
-public class HibernateExceptionTranslator implements PersistenceExceptionTranslator {
+@CompileStatic
+class HibernateExceptionTranslator implements PersistenceExceptionTranslator {
 
-    @Nullable
-    private SQLExceptionTranslator jdbcExceptionTranslator;
+    private SQLExceptionTranslator jdbcExceptionTranslator
 
     /**
      * Set the JDBC exception translator for Hibernate exception translation purposes.
@@ -60,23 +57,22 @@ public class HibernateExceptionTranslator implements PersistenceExceptionTransla
      * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
      * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
      */
-    public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {
-        this.jdbcExceptionTranslator = jdbcExceptionTranslator;
+    void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {
+        this.jdbcExceptionTranslator = jdbcExceptionTranslator
     }
 
     @Override
-    @Nullable
-    public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
-        if (ex instanceof HibernateException hibernateEx) {
-            return convertHibernateAccessException(hibernateEx);
+    DataAccessException translateExceptionIfPossible(RuntimeException ex) {
+        if (ex instanceof HibernateException) {
+            return convertHibernateAccessException((HibernateException) ex)
         }
         if (ex instanceof PersistenceException) {
-            if (ex.getCause() instanceof HibernateException hibernateEx) {
-                return convertHibernateAccessException(hibernateEx);
+            if (ex.getCause() instanceof HibernateException) {
+                return convertHibernateAccessException((HibernateException) ex.getCause())
             }
-            return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
+            return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex)
         }
-        return null;
+        return null
     }
 
     /**
@@ -89,14 +85,15 @@ public class HibernateExceptionTranslator implements PersistenceExceptionTransla
      * @see SessionFactoryUtils#convertHibernateAccessException
      */
     protected DataAccessException convertHibernateAccessException(HibernateException ex) {
-        if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException jdbcEx) {
+        if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) {
+            JDBCException jdbcEx = (JDBCException) ex
             DataAccessException dae = this.jdbcExceptionTranslator.translate(
-                    "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException());
+                    'Hibernate operation: ' + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException())
             if (dae != null) {
-                return dae;
+                return dae
             }
         }
-        return SessionFactoryUtils.convertHibernateAccessException(ex);
+        return SessionFactoryUtils.convertHibernateAccessException(ex)
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.groovy
similarity index 53%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.groovy
index 5e6e542e55..cf1760b536 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateJdbcException.groovy
@@ -13,15 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
+import java.sql.SQLException
 
-import java.sql.SQLException;
-
-import org.hibernate.JDBCException;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.dao.UncategorizedDataAccessException;
+import groovy.transform.CompileStatic
+import org.hibernate.JDBCException
+import org.springframework.dao.UncategorizedDataAccessException
 
 /**
  * Hibernate-specific subclass of UncategorizedDataAccessException,
@@ -31,29 +29,27 @@ import org.springframework.dao.UncategorizedDataAccessException;
  * @since 4.2
  * @see SessionFactoryUtils#convertHibernateAccessException
  */
-@SuppressWarnings("serial")
-public class HibernateJdbcException extends UncategorizedDataAccessException {
+@CompileStatic
+@SuppressWarnings('serial')
+class HibernateJdbcException extends UncategorizedDataAccessException {
 
-    public HibernateJdbcException(JDBCException ex) {
-        super("JDBC exception on Hibernate data access: SQLException for SQL [" + ex.getSQL() + "]; SQL state [" +
-                ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex);
+    HibernateJdbcException(JDBCException ex) {
+        super('JDBC exception on Hibernate data access: SQLException for SQL [' + ex.getSQL() + ']; SQL state [' +
+                ex.getSQLState() + ']; error code [' + ex.getErrorCode() + ']; ' + ex.getMessage(), ex)
     }
 
     /**
      * Return the underlying SQLException.
      */
-    @SuppressWarnings("NullAway")
-    public SQLException getSQLException() {
-        return ((JDBCException) getCause()).getSQLException();
+    SQLException getSQLException() {
+        return ((JDBCException) getCause()).getSQLException()
     }
 
     /**
      * Return the SQL that led to the problem.
      */
-    @Nullable
-    @SuppressWarnings("NullAway")
-    public String getSql() {
-        return ((JDBCException) getCause()).getSQL();
+    String getSql() {
+        return ((JDBCException) getCause()).getSQL()
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.groovy
similarity index 63%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.groovy
index 6559e7011a..616824aa63 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateObjectRetrievalFailureException.groovy
@@ -13,16 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.HibernateException;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.WrongClassException;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.orm.ObjectRetrievalFailureException;
-import org.springframework.util.ReflectionUtils;
+import groovy.transform.CompileStatic
+import groovy.transform.PackageScope
+import org.hibernate.HibernateException
+import org.hibernate.UnresolvableObjectException
+import org.hibernate.WrongClassException
+import org.springframework.orm.ObjectRetrievalFailureException
+import org.springframework.util.ReflectionUtils
 
 /**
  * Hibernate-specific subclass of ObjectRetrievalFailureException.
@@ -32,26 +31,26 @@ import org.springframework.util.ReflectionUtils;
  * @since 4.2
  * @see SessionFactoryUtils#convertHibernateAccessException
  */
-@SuppressWarnings("serial")
-public class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException {
+@CompileStatic
+@SuppressWarnings('serial')
+class HibernateObjectRetrievalFailureException extends ObjectRetrievalFailureException {
 
-    public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) {
-        super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex);
+    HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) {
+        super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex)
     }
 
-    public HibernateObjectRetrievalFailureException(WrongClassException ex) {
-        super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex);
+    HibernateObjectRetrievalFailureException(WrongClassException ex) {
+        super(ex.getEntityName(), getIdentifier(ex), ex.getMessage(), ex)
     }
 
-    @Nullable
+    @PackageScope
     static Object getIdentifier(HibernateException hibEx) {
         try {
             // getIdentifier declares Serializable return value on 5.x but Object on 6.x
             // -> not binary compatible, let's invoke it reflectively for the time being
-            return ReflectionUtils.invokeMethod(hibEx.getClass().getMethod("getIdentifier"), hibEx);
-        }
-        catch (NoSuchMethodException ex) {
-            return null;
+            return ReflectionUtils.invokeMethod(hibEx.getClass().getMethod('getIdentifier'), hibEx)
+        } catch (NoSuchMethodException ex) {
+            return null
         }
     }
 
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.groovy
similarity index 59%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.groovy
index 523a2d161b..b46d148a7a 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateOptimisticLockingFailureException.groovy
@@ -13,14 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.StaleStateException;
-import org.hibernate.dialect.lock.OptimisticEntityLockException;
-
-import org.springframework.orm.ObjectOptimisticLockingFailureException;
+import groovy.transform.CompileStatic
+import org.hibernate.StaleObjectStateException
+import org.hibernate.StaleStateException
+import org.hibernate.dialect.lock.OptimisticEntityLockException
+import org.springframework.orm.ObjectOptimisticLockingFailureException
 
 /**
  * Hibernate-specific subclass of ObjectOptimisticLockingFailureException.
@@ -31,19 +30,20 @@ import org.springframework.orm.ObjectOptimisticLockingFailureException;
  * @since 4.2
  * @see SessionFactoryUtils#convertHibernateAccessException
  */
-@SuppressWarnings("serial")
-public class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException {
+@CompileStatic
+@SuppressWarnings('serial')
+class HibernateOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException {
 
-    public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) {
-        super(ex.getEntityName(), HibernateObjectRetrievalFailureException.getIdentifier(ex), ex.getMessage(), ex);
+    HibernateOptimisticLockingFailureException(StaleObjectStateException ex) {
+        super(ex.getEntityName(), HibernateObjectRetrievalFailureException.getIdentifier(ex), ex.getMessage(), ex)
     }
 
-    public HibernateOptimisticLockingFailureException(StaleStateException ex) {
-        super(ex.getMessage(), ex);
+    HibernateOptimisticLockingFailureException(StaleStateException ex) {
+        super(ex.getMessage(), ex)
     }
 
-    public HibernateOptimisticLockingFailureException(OptimisticEntityLockException ex) {
-        super(ex.getMessage(), ex);
+    HibernateOptimisticLockingFailureException(OptimisticEntityLockException ex) {
+        super(ex.getMessage(), ex)
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.groovy
similarity index 65%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.groovy
index 03a2bf2712..0c4977d63a 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateQueryException.groovy
@@ -13,13 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.QueryException;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.dao.InvalidDataAccessResourceUsageException;
+import groovy.transform.CompileStatic
+import org.hibernate.QueryException
+import org.springframework.dao.InvalidDataAccessResourceUsageException
 
 /**
  * Hibernate-specific subclass of InvalidDataAccessResourceUsageException,
@@ -29,20 +27,20 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
  * @since 4.2
  * @see SessionFactoryUtils#convertHibernateAccessException
  */
-@SuppressWarnings("serial")
-public class HibernateQueryException extends InvalidDataAccessResourceUsageException {
+@CompileStatic
+@SuppressWarnings('serial')
+class HibernateQueryException extends InvalidDataAccessResourceUsageException {
 
-    public HibernateQueryException(QueryException ex) {
-        super(ex.getMessage(), ex);
+    HibernateQueryException(QueryException ex) {
+        super(ex.getMessage(), ex)
     }
 
     /**
      * Return the HQL query string that was invalid.
      */
-    @Nullable
-    public String getQueryString() {
-        QueryException cause = (QueryException) getCause();
-        return (cause != null ? cause.getQueryString() : null);
+    String getQueryString() {
+        QueryException cause = (QueryException) getCause()
+        return (cause != null ? cause.getQueryString() : null)
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.groovy
similarity index 70%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.groovy
index dbfadb0d78..65790b227d 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/HibernateSystemException.groovy
@@ -13,13 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.HibernateException;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.dao.UncategorizedDataAccessException;
+import groovy.transform.CompileStatic
+import org.hibernate.HibernateException
+import org.springframework.dao.UncategorizedDataAccessException
 
 /**
  * Hibernate-specific subclass of UncategorizedDataAccessException,
@@ -30,16 +28,17 @@ import org.springframework.dao.UncategorizedDataAccessException;
  * @since 4.2
  * @see SessionFactoryUtils#convertHibernateAccessException
  */
-@SuppressWarnings("serial")
-public class HibernateSystemException extends UncategorizedDataAccessException {
+@CompileStatic
+@SuppressWarnings('serial')
+class HibernateSystemException extends UncategorizedDataAccessException {
 
     /**
      * Create a new HibernateSystemException,
      * wrapping an arbitrary HibernateException.
      * @param cause the HibernateException thrown
      */
-    public HibernateSystemException(@Nullable HibernateException cause) {
-        super(cause != null ? cause.getMessage() : null, cause);
+    HibernateSystemException(HibernateException cause) {
+        super(cause != null ? cause.getMessage() : null, cause)
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.groovy
similarity index 51%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.groovy
index 7a03919370..08746fff8a 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SessionHolder.groovy
@@ -13,15 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.FlushMode;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.orm.jpa.EntityManagerHolder;
+import groovy.transform.CompileStatic
+import org.hibernate.FlushMode
+import org.hibernate.Session
+import org.hibernate.Transaction
+import org.springframework.orm.jpa.EntityManagerHolder
 
 /**
  * Resource holder wrapping a Hibernate {@link Session} (plus an optional {@link Transaction}).
@@ -36,46 +34,43 @@ import org.springframework.orm.jpa.EntityManagerHolder;
  * @see HibernateTransactionManager
  * @see SessionFactoryUtils
  */
-public class SessionHolder extends EntityManagerHolder {
+@CompileStatic
+class SessionHolder extends EntityManagerHolder {
 
-    @Nullable
-    private Transaction transaction;
+    private Transaction transaction
 
-    @Nullable
-    private FlushMode previousFlushMode;
+    private FlushMode previousFlushMode
 
-    public SessionHolder(Session session) {
-        super(session);
+    SessionHolder(Session session) {
+        super(session)
     }
 
-    public Session getSession() {
-        return (Session) getEntityManager();
+    Session getSession() {
+        return (Session) getEntityManager()
     }
 
-    public void setTransaction(@Nullable Transaction transaction) {
-        this.transaction = transaction;
-        setTransactionActive(transaction != null);
+    void setTransaction(Transaction transaction) {
+        this.transaction = transaction
+        setTransactionActive(transaction != null)
     }
 
-    @Nullable
-    public Transaction getTransaction() {
-        return this.transaction;
+    Transaction getTransaction() {
+        return this.transaction
     }
 
-    public void setPreviousFlushMode(@Nullable FlushMode previousFlushMode) {
-        this.previousFlushMode = previousFlushMode;
+    void setPreviousFlushMode(FlushMode previousFlushMode) {
+        this.previousFlushMode = previousFlushMode
     }
 
-    @Nullable
-    public FlushMode getPreviousFlushMode() {
-        return this.previousFlushMode;
+    FlushMode getPreviousFlushMode() {
+        return this.previousFlushMode
     }
 
     @Override
-    public void clear() {
-        super.clear();
-        this.transaction = null;
-        this.previousFlushMode = null;
+    void clear() {
+        super.clear()
+        this.transaction = null
+        this.previousFlushMode = null
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.groovy
similarity index 56%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.groovy
index 253858e2a0..2c793d0cec 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringFlushSynchronization.groovy
@@ -13,13 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.Session;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.transaction.support.TransactionSynchronization;
+import groovy.transform.CompileStatic
+import org.hibernate.Session
+import org.springframework.transaction.support.TransactionSynchronization
 
 /**
  * Simple synchronization adapter that propagates a {@code flush()} call
@@ -28,27 +26,30 @@ import org.springframework.transaction.support.TransactionSynchronization;
  * @author Juergen Hoeller
  * @since 4.2
  */
-public class SpringFlushSynchronization implements TransactionSynchronization {
+@CompileStatic
+class SpringFlushSynchronization implements TransactionSynchronization {
 
-    private final Session session;
+    private final Session session
 
-    public SpringFlushSynchronization(Session session) {
-        this.session = session;
+    SpringFlushSynchronization(Session session) {
+        this.session = session
     }
 
     @Override
-    public void flush() {
-        SessionFactoryUtils.flush(this.session, false);
+    void flush() {
+        SessionFactoryUtils.flush(this.session, false)
     }
 
     @Override
-    public boolean equals(@Nullable Object other) {
-        return (this == other || (other instanceof SpringFlushSynchronization that && this.session == that.session));
+    boolean equals(Object other) {
+        // Reference identity on both counts, as in the original.
+        return this.is(other) ||
+                (other instanceof SpringFlushSynchronization && this.session.is(((SpringFlushSynchronization) other).@session))
     }
 
     @Override
-    public int hashCode() {
-        return this.session.hashCode();
+    int hashCode() {
+        return this.session.hashCode()
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.groovy
similarity index 63%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.groovy
index 914384f4e3..31fbed7a1e 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringJtaSessionContext.groovy
@@ -13,15 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.FlushMode;
-import org.hibernate.Session;
-import org.hibernate.context.internal.JTASessionContext;
-import org.hibernate.engine.spi.SessionFactoryImplementor;
-
-import org.springframework.transaction.support.TransactionSynchronizationManager;
+import groovy.transform.CompileStatic
+import org.hibernate.FlushMode
+import org.hibernate.Session
+import org.hibernate.context.internal.JTASessionContext
+import org.hibernate.engine.spi.SessionFactoryImplementor
+import org.springframework.transaction.support.TransactionSynchronizationManager
 
 /**
  * Spring-specific subclass of Hibernate's JTASessionContext,
@@ -30,20 +29,21 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
  * @author Juergen Hoeller
  * @since 4.2
  */
-@SuppressWarnings("serial")
-public class SpringJtaSessionContext extends JTASessionContext {
+@CompileStatic
+@SuppressWarnings('serial')
+class SpringJtaSessionContext extends JTASessionContext {
 
-    public SpringJtaSessionContext(SessionFactoryImplementor factory) {
-        super(factory);
+    SpringJtaSessionContext(SessionFactoryImplementor factory) {
+        super(factory)
     }
 
     @Override
     protected Session buildOrObtainSession() {
-        Session session = super.buildOrObtainSession();
+        Session session = super.buildOrObtainSession()
         if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
-            session.setHibernateFlushMode(FlushMode.MANUAL);
+            session.setHibernateFlushMode(FlushMode.MANUAL)
         }
-        return session;
+        return session
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.groovy
similarity index 60%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.groovy
index a1c5a1cb78..b884f86079 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionContext.groovy
@@ -13,24 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.grails.orm.hibernate.support.hibernate7
 
-package org.grails.orm.hibernate.support.hibernate7;
-
-import jakarta.transaction.Status;
-import jakarta.transaction.SystemException;
-import jakarta.transaction.TransactionManager;
-
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.context.spi.CurrentSessionContext;
-import org.hibernate.engine.spi.SessionFactoryImplementor;
-import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.orm.jpa.EntityManagerHolder;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
+import groovy.transform.CompileStatic
+import jakarta.transaction.Status
+import jakarta.transaction.SystemException
+import jakarta.transaction.TransactionManager
+import org.apache.commons.logging.LogFactory
+import org.hibernate.FlushMode
+import org.hibernate.HibernateException
+import org.hibernate.Session
+import org.hibernate.context.spi.CurrentSessionContext
+import org.hibernate.engine.spi.SessionFactoryImplementor
+import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform
+import org.springframework.orm.jpa.EntityManagerHolder
+import org.springframework.transaction.support.TransactionSynchronizationManager
 
 /**
  * Implementation of Hibernate 3.1's {@link CurrentSessionContext} interface
@@ -44,101 +41,94 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
  * @author Juergen Hoeller
  * @since 4.2
  */
-@SuppressWarnings("serial")
-public class SpringSessionContext implements CurrentSessionContext {
+@CompileStatic
+@SuppressWarnings('serial')
+class SpringSessionContext implements CurrentSessionContext {
 
-    private final SessionFactoryImplementor sessionFactory;
+    private final SessionFactoryImplementor sessionFactory
 
-    @Nullable
-    private TransactionManager transactionManager;
+    private TransactionManager transactionManager
 
-    @Nullable
-    private CurrentSessionContext jtaSessionContext;
+    private CurrentSessionContext jtaSessionContext
 
     /**
      * Create a new SpringSessionContext for the given Hibernate SessionFactory.
      * @param sessionFactory the SessionFactory to provide current Sessions for
      */
-    public SpringSessionContext(SessionFactoryImplementor sessionFactory) {
-        this.sessionFactory = sessionFactory;
+    SpringSessionContext(SessionFactoryImplementor sessionFactory) {
+        this.sessionFactory = sessionFactory
         try {
-            JtaPlatform jtaPlatform = sessionFactory.getServiceRegistry().getService(JtaPlatform.class);
-            this.transactionManager = jtaPlatform.retrieveTransactionManager();
+            JtaPlatform jtaPlatform = sessionFactory.getServiceRegistry().getService(JtaPlatform)
+            this.transactionManager = jtaPlatform.retrieveTransactionManager()
             if (this.transactionManager != null) {
-                this.jtaSessionContext = new SpringJtaSessionContext(sessionFactory);
+                this.jtaSessionContext = new SpringJtaSessionContext(sessionFactory)
             }
-        }
-        catch (Exception ex) {
-            LogFactory.getLog(SpringSessionContext.class).warn(
-                    "Could not introspect Hibernate JtaPlatform for SpringJtaSessionContext", ex);
+        } catch (Exception ex) {
+            LogFactory.getLog(SpringSessionContext).warn(
+                    'Could not introspect Hibernate JtaPlatform for SpringJtaSessionContext', ex)
         }
     }
 
-
     /**
      * Retrieve the Spring-managed Session for the current thread, if any.
      */
     @Override
-    public Session currentSession() throws HibernateException {
-        Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
-        if (value instanceof Session session) {
-            return session;
-        }
-        else if (value instanceof SessionHolder sessionHolder) {
+    Session currentSession() throws HibernateException {
+        Object value = TransactionSynchronizationManager.getResource(this.sessionFactory)
+        if (value instanceof Session) {
+            return (Session) value
+        } else if (value instanceof SessionHolder) {
             // HibernateTransactionManager
-            Session session = sessionHolder.getSession();
+            SessionHolder sessionHolder = (SessionHolder) value
+            Session session = sessionHolder.getSession()
             if (!sessionHolder.isSynchronizedWithTransaction() &&
                     TransactionSynchronizationManager.isSynchronizationActive()) {
                 TransactionSynchronizationManager.registerSynchronization(
-                        new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
-                sessionHolder.setSynchronizedWithTransaction(true);
+                        new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false))
+                sessionHolder.setSynchronizedWithTransaction(true)
                 // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
                 // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
-                FlushMode flushMode = session.getHibernateFlushMode();
-                if (flushMode.equals(FlushMode.MANUAL) &&
+                FlushMode flushMode = session.getHibernateFlushMode()
+                if (flushMode == FlushMode.MANUAL &&
                         !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
-                    session.setHibernateFlushMode(FlushMode.AUTO);
-                    sessionHolder.setPreviousFlushMode(flushMode);
+                    session.setHibernateFlushMode(FlushMode.AUTO)
+                    sessionHolder.setPreviousFlushMode(flushMode)
                 }
             }
-            return session;
-        }
-        else if (value instanceof EntityManagerHolder entityManagerHolder) {
+            return session
+        } else if (value instanceof EntityManagerHolder) {
             // JpaTransactionManager
-            return entityManagerHolder.getEntityManager().unwrap(Session.class);
+            return ((EntityManagerHolder) value).getEntityManager().unwrap(Session)
         }
 
         if (this.transactionManager != null && this.jtaSessionContext != null) {
             try {
                 if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
-                    Session session = this.jtaSessionContext.currentSession();
+                    Session session = this.jtaSessionContext.currentSession()
                     if (TransactionSynchronizationManager.isSynchronizationActive()) {
                         TransactionSynchronizationManager.registerSynchronization(
-                                new SpringFlushSynchronization(session));
+                                new SpringFlushSynchronization(session))
                     }
-                    return session;
+                    return session
                 }
-            }
-            catch (SystemException ex) {
-                throw new HibernateException("JTA TransactionManager found but status check failed", ex);
+            } catch (SystemException ex) {
+                throw new HibernateException('JTA TransactionManager found but status check failed', ex)
             }
         }
 
         if (TransactionSynchronizationManager.isSynchronizationActive()) {
-            Session session = this.sessionFactory.openSession();
+            Session session = this.sessionFactory.openSession()
             if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
-                session.setHibernateFlushMode(FlushMode.MANUAL);
+                session.setHibernateFlushMode(FlushMode.MANUAL)
             }
-            SessionHolder sessionHolder = new SessionHolder(session);
+            SessionHolder sessionHolder = new SessionHolder(session)
             TransactionSynchronizationManager.registerSynchronization(
-                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
-            TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
-            sessionHolder.setSynchronizedWithTransaction(true);
-            return session;
-        }
-        else {
-            throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
+                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true))
+            TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder)
+            sessionHolder.setSynchronizedWithTransaction(true)
+            return session
         }
+        throw new HibernateException('Could not obtain transaction-synchronized Session for current thread')
     }
 
 }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.groovy
similarity index 55%
rename from grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.java
rename to grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.groovy
index 3755feefc0..2824e89320 100644
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.java
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/SpringSessionSynchronization.groovy
@@ -13,18 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package org.grails.orm.hibernate.support.hibernate7;
-
-import org.hibernate.FlushMode;
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.engine.spi.SessionImplementor;
-
-import org.springframework.core.Ordered;
-import org.springframework.dao.DataAccessException;
-import org.springframework.transaction.support.TransactionSynchronization;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
+package org.grails.orm.hibernate.support.hibernate7
+
+import groovy.transform.CompileStatic
+import org.hibernate.FlushMode
+import org.hibernate.Session
+import org.hibernate.SessionFactory
+import org.hibernate.engine.spi.SessionImplementor
+import org.springframework.core.Ordered
+import org.springframework.dao.DataAccessException
+import org.springframework.transaction.support.TransactionSynchronization
+import org.springframework.transaction.support.TransactionSynchronizationManager
 
 /**
  * Callback for resource cleanup at the end of a Spring-managed transaction
@@ -33,111 +32,111 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
  * @author Juergen Hoeller
  * @since 4.2
  */
-public class SpringSessionSynchronization implements TransactionSynchronization, Ordered {
+@CompileStatic
+class SpringSessionSynchronization implements TransactionSynchronization, Ordered {
 
-    private final SessionHolder sessionHolder;
+    private final SessionHolder sessionHolder
 
-    private final SessionFactory sessionFactory;
+    private final SessionFactory sessionFactory
 
-    private final boolean newSession;
+    private final boolean newSession
 
-    private boolean holderActive = true;
+    private boolean holderActive = true
 
-    public SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory) {
-        this(sessionHolder, sessionFactory, false);
+    SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory) {
+        this(sessionHolder, sessionFactory, false)
     }
 
-    public SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory, boolean newSession) {
-        this.sessionHolder = sessionHolder;
-        this.sessionFactory = sessionFactory;
-        this.newSession = newSession;
+    SpringSessionSynchronization(SessionHolder sessionHolder, SessionFactory sessionFactory, boolean newSession) {
+        this.sessionHolder = sessionHolder
+        this.sessionFactory = sessionFactory
+        this.newSession = newSession
     }
 
     private Session getCurrentSession() {
-        return this.sessionHolder.getSession();
+        return this.sessionHolder.getSession()
     }
 
     @Override
-    public int getOrder() {
-        return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER;
+    int getOrder() {
+        return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER
     }
 
     @Override
-    public void suspend() {
+    void suspend() {
         if (this.holderActive) {
-            TransactionSynchronizationManager.unbindResource(this.sessionFactory);
+            TransactionSynchronizationManager.unbindResource(this.sessionFactory)
             // Eagerly disconnect the Session here, to make release mode "on_close" work on JBoss.
-            Session session = getCurrentSession();
-            if (session instanceof SessionImplementor sessionImpl) {
-                sessionImpl.getJdbcCoordinator().getLogicalConnection().manualDisconnect();
+            Session session = getCurrentSession()
+            if (session instanceof SessionImplementor) {
+                ((SessionImplementor) session).getJdbcCoordinator().getLogicalConnection().manualDisconnect()
             }
         }
     }
 
     @Override
-    public void resume() {
+    void resume() {
         if (this.holderActive) {
-            TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder);
+            TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder)
         }
     }
 
     @Override
-    public void flush() {
-        SessionFactoryUtils.flush(getCurrentSession(), false);
+    void flush() {
+        SessionFactoryUtils.flush(getCurrentSession(), false)
     }
 
     @Override
-    public void beforeCommit(boolean readOnly) throws DataAccessException {
+    void beforeCommit(boolean readOnly) throws DataAccessException {
         if (!readOnly) {
-            Session session = getCurrentSession();
+            Session session = getCurrentSession()
             // Read-write transaction -> flush the Hibernate Session.
             // Further check: only flush when not FlushMode.MANUAL.
-            if (!FlushMode.MANUAL.equals(session.getHibernateFlushMode())) {
-                SessionFactoryUtils.flush(getCurrentSession(), true);
+            if (session.getHibernateFlushMode() != FlushMode.MANUAL) {
+                SessionFactoryUtils.flush(getCurrentSession(), true)
             }
         }
     }
 
     @Override
-    public void beforeCompletion() {
+    void beforeCompletion() {
         try {
-            Session session = this.sessionHolder.getSession();
+            Session session = this.sessionHolder.getSession()
             if (this.sessionHolder.getPreviousFlushMode() != null) {
                 // In case of pre-bound Session, restore previous flush mode.
-                session.setHibernateFlushMode(this.sessionHolder.getPreviousFlushMode());
+                session.setHibernateFlushMode(this.sessionHolder.getPreviousFlushMode())
             }
             // Eagerly disconnect the Session here, to make release mode "on_close" work nicely.
-            if (session instanceof SessionImplementor sessionImpl) {
-                sessionImpl.getJdbcCoordinator().getLogicalConnection().manualDisconnect();
+            if (session instanceof SessionImplementor) {
+                ((SessionImplementor) session).getJdbcCoordinator().getLogicalConnection().manualDisconnect()
             }
-        }
-        finally {
+        } finally {
             // Unbind at this point if it's a new Session...
             if (this.newSession) {
-                TransactionSynchronizationManager.unbindResource(this.sessionFactory);
-                this.holderActive = false;
+                TransactionSynchronizationManager.unbindResource(this.sessionFactory)
+                this.holderActive = false
             }
         }
     }
 
     @Override
-    public void afterCommit() {
+    void afterCommit() {
+        // no-op
     }
 
     @Override
-    public void afterCompletion(int status) {
+    void afterCompletion(int status) {
         try {
             if (status != STATUS_COMMITTED) {
                 // Clear all pending inserts/updates/deletes in the Session.
                 // Necessary for pre-bound Sessions, to avoid inconsistent state.
-                this.sessionHolder.getSession().clear();
+                this.sessionHolder.getSession().clear()
             }
-        }
-        finally {
-            this.sessionHolder.setSynchronizedWithTransaction(false);
+        } finally {
+            this.sessionHolder.setSynchronizedWithTransaction(false)
             // Call close() at this point if it's a new Session...
             if (this.newSession) {
-                SessionFactoryUtils.closeSession(this.sessionHolder.getSession());
+                SessionFactoryUtils.closeSession(this.sessionHolder.getSession())
             }
         }
     }
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.groovy b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.groovy
new file mode 100644
index 0000000000..a82576fcd1
--- /dev/null
+++ b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.groovy
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.grails.orm.hibernate.support.hibernate7.support
+
+import java.util.concurrent.Callable
+
+import groovy.transform.CompileStatic
+import groovy.transform.PackageScope
+import org.apache.commons.logging.Log
+import org.apache.commons.logging.LogFactory
+import org.hibernate.SessionFactory
+import org.springframework.transaction.support.TransactionSynchronizationManager
+import org.springframework.web.context.request.NativeWebRequest
+import org.springframework.web.context.request.async.CallableProcessingInterceptor
+import org.springframework.web.context.request.async.DeferredResult
+import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor
+
+import org.grails.orm.hibernate.support.hibernate7.SessionFactoryUtils
+import org.grails.orm.hibernate.support.hibernate7.SessionHolder
+
+/**
+ * An interceptor with asynchronous web requests used in OpenSessionInViewFilter and
+ * OpenSessionInViewInterceptor.
+ *
+ * Ensures the following:
+ * 1) The session is bound/unbound when "callable processing" is started
+ * 2) The session is closed if an async request times out or an error occurred
+ *
+ * @author Rossen Stoyanchev
+ * @since 4.2
+ */
+@CompileStatic
+@PackageScope
+class AsyncRequestInterceptor implements CallableProcessingInterceptor, DeferredResultProcessingInterceptor {
+
+    private static final Log LOG = LogFactory.getLog(AsyncRequestInterceptor)
+
+    private final SessionFactory sessionFactory
+
+    private final SessionHolder sessionHolder
+
+    private volatile boolean timeoutInProgress
+
+    private volatile boolean errorInProgress
+
+    AsyncRequestInterceptor(SessionFactory sessionFactory, SessionHolder sessionHolder) {
+        this.sessionFactory = sessionFactory
+        this.sessionHolder = sessionHolder
+    }
+
+    @Override
+    def <T> void preProcess(NativeWebRequest request, Callable<T> task) {
+        bindSession()
+    }
+
+    void bindSession() {
+        this.timeoutInProgress = false
+        this.errorInProgress = false
+        TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder)
+    }
+
+    @Override
+    def <T> void postProcess(NativeWebRequest request, Callable<T> task, Object concurrentResult) {
+        TransactionSynchronizationManager.unbindResource(this.sessionFactory)
+    }
+
+    @Override
+    def <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) {
+        this.timeoutInProgress = true
+        return RESULT_NONE  // give other interceptors a chance to handle the timeout
+    }
+
+    @Override
+    def <T> Object handleError(NativeWebRequest request, Callable<T> task, Throwable t) {
+        this.errorInProgress = true
+        return RESULT_NONE  // give other interceptors a chance to handle the error
+    }
+
+    @Override
+    def <T> void afterCompletion(NativeWebRequest request, Callable<T> task) throws Exception {
+        closeSession()
+    }
+
+    private void closeSession() {
+        if (this.timeoutInProgress || this.errorInProgress) {
+            LOG.debug('Closing Hibernate Session after async request timeout/error')
+            SessionFactoryUtils.closeSession(this.sessionHolder.getSession())
+        }
+    }
+
+    // Implementation of DeferredResultProcessingInterceptor methods
+
+    @Override
+    def <T> boolean handleTimeout(NativeWebRequest request, DeferredResult<T> deferredResult) {
+        this.timeoutInProgress = true
+        return true  // give other interceptors a chance to handle the timeout
+    }
+
+    @Override
+    def <T> boolean handleError(NativeWebRequest request, DeferredResult<T> deferredResult, Throwable t) {
+        this.errorInProgress = true
+        return true  // give other interceptors a chance to handle the error
+    }
+
+    @Override
+    def <T> void afterCompletion(NativeWebRequest request, DeferredResult<T> deferredResult) {
+        closeSession()
+    }
+
+}
diff --git a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.java b/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.java
deleted file mode 100644
index 161687d957..0000000000
--- a/grails-data-hibernate7/spring-orm/src/main/groovy/org/grails/orm/hibernate/support/hibernate7/support/AsyncRequestInterceptor.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2002-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.grails.orm.hibernate.support.hibernate7.support;
-
-import java.util.concurrent.Callable;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.SessionFactory;
-import org.jspecify.annotations.Nullable;
-
-import org.springframework.transaction.support.TransactionSynchronizationManager;
-import org.springframework.web.context.request.NativeWebRequest;
-import org.springframework.web.context.request.async.CallableProcessingInterceptor;
-import org.springframework.web.context.request.async.DeferredResult;
-import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
-
-import org.grails.orm.hibernate.support.hibernate7.SessionFactoryUtils;
-import org.grails.orm.hibernate.support.hibernate7.SessionHolder;
-
-/**
- * An interceptor with asynchronous web requests used in OpenSessionInViewFilter and
- * OpenSessionInViewInterceptor.
- *
- * Ensures the following:
- * 1) The session is bound/unbound when "callable processing" is started
- * 2) The session is closed if an async request times out or an error occurred
- *
- * @author Rossen Stoyanchev
- * @since 4.2
- */
-class AsyncRequestInterceptor implements CallableProcessingInterceptor, DeferredResultProcessingInterceptor {
-
-    private static final Log logger = LogFactory.getLog(AsyncRequestInterceptor.class);
-
-    private final SessionFactory sessionFactory;
-
-    private final SessionHolder sessionHolder;
-
-    private volatile boolean timeoutInProgress;
-
-    private volatile boolean errorInProgress;
-
-    public AsyncRequestInterceptor(SessionFactory sessionFactory, SessionHolder sessionHolder) {
-        this.sessionFactory = sessionFactory;
-        this.sessionHolder = sessionHolder;
-    }
-
-    @Override
-    public <T> void preProcess(NativeWebRequest request, Callable<T> task) {
-        bindSession();
-    }
-
-    public void bindSession() {
-        this.timeoutInProgress = false;
-        this.errorInProgress = false;
-        TransactionSynchronizationManager.bindResource(this.sessionFactory, this.sessionHolder);
-    }
-
-    @Override
-    public <T> void postProcess(NativeWebRequest request, Callable<T> task, @Nullable Object concurrentResult) {
-        TransactionSynchronizationManager.unbindResource(this.sessionFactory);
-    }
-
-    @Override
-    public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) {
-        this.timeoutInProgress = true;
-        return RESULT_NONE;  // give other interceptors a chance to handle the timeout
-    }
-
-    @Override
-    public <T> Object handleError(NativeWebRequest request, Callable<T> task, Throwable t) {
-        this.errorInProgress = true;
-        return RESULT_NONE;  // give other interceptors a chance to handle the error
-    }
-
-    @Override
-    public <T> void afterCompletion(NativeWebRequest request, Callable<T> task) throws Exception {
-        closeSession();
-    }
-
-    private void closeSession() {
-        if (this.timeoutInProgress || this.errorInProgress) {
-            logger.debug("Closing Hibernate Session after async request timeout/error");
-            SessionFactoryUtils.closeSession(this.sessionHolder.getSession());
-        }
-    }
-
-
-    // Implementation of DeferredResultProcessingInterceptor methods
-
-    @Override
-    public <T> boolean handleTimeout(NativeWebRequest request, DeferredResult<T> deferredResult) {
-        this.timeoutInProgress = true;
-        return true;  // give other interceptors a chance to handle the timeout
-    }
-
-    @Override
-    public <T> boolean handleError(NativeWebRequest request, DeferredResult<T> deferredResult, Throwable t) {
-        this.errorInProgress = true;
-        return true;  // give other interceptors a chance to handle the error
-    }
-
-    @Override
-    public <T> void afterCompletion(NativeWebRequest request, DeferredResult<T> deferredResult) {
-        closeSession();
-    }
-
-}