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

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

commit 2ee2b852dc8fb669507e21c5ecb47ae2a3751797
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Fri Feb 27 15:23:29 2026 -0600

    Hibernate 7.2
---
 gradle.properties                                  |   2 +-
 .../orm/hibernate/GrailsHibernateTemplate.java     |  11 +-
 .../domainbinding/binder/SimpleValueBinder.java    |   9 +-
 .../domainbinding/util/BasicValueIdCreator.java    |  10 +-
 .../hibernate/support/ClosureEventListener.java    | 364 +++++++--------------
 .../HibernateDialectDetectorFactoryBean.java       |   5 +
 .../util/GeneratorCreationContextWrapper.java      |  93 ++++++
 .../domainbinding/BasicValueIdCreatorSpec.groovy   |  10 +-
 .../GrailsSequenceGeneratorEnumSpec.groovy         |   5 +-
 9 files changed, 251 insertions(+), 258 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 31f8d9a58a..e87a20b74e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -36,7 +36,7 @@ gparsVersion=1.2.1
 # and 
grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/gradleWrapperProperties.rocker.raw
 gradleToolingApiVersion=8.14.4
 hibernate5Version=5.6.15.Final
-hibernate7Version=7.1.11.Final
+hibernate7Version=7.2.5.Final
 #hibernate7Version=7.2.4.Final
 javassistVersion=3.30.2-GA
 jnrPosixVersion=3.1.20
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 54bf894f8b..474982d0d8 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
@@ -37,7 +37,6 @@ import java.util.List;
 import javax.sql.DataSource;
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.hibernate.*;
-import 
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
 import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
 import org.hibernate.engine.spi.SessionFactoryImplementor;
 import org.hibernate.engine.spi.SessionImplementor;
@@ -97,12 +96,12 @@ public class GrailsHibernateTemplate implements 
IHibernateTemplate {
         ((SessionFactoryImplementor) sessionFactory)
             .getServiceRegistry()
             .getService(ConnectionProvider.class);
-    if (connectionProvider instanceof DatasourceConnectionProviderImpl) {
-      this.dataSource = ((DatasourceConnectionProviderImpl) 
connectionProvider).getDataSource();
-      if (dataSource instanceof TransactionAwareDataSourceProxy) {
-        this.dataSource = ((TransactionAwareDataSourceProxy) 
dataSource).getTargetDataSource();
+    this.dataSource = connectionProvider.unwrap(DataSource.class);
+    if (this.dataSource != null) {
+      if (this.dataSource instanceof TransactionAwareDataSourceProxy) {
+        this.dataSource = ((TransactionAwareDataSourceProxy) 
this.dataSource).getTargetDataSource();
       }
-      jdbcExceptionTranslator = new 
SQLErrorCodeSQLExceptionTranslator(dataSource);
+      jdbcExceptionTranslator = new 
SQLErrorCodeSQLExceptionTranslator(this.dataSource);
     } else {
       // must be in unit test mode, setup default translator
       SQLErrorCodeSQLExceptionTranslator sqlErrorCodeSQLExceptionTranslator =
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
index 417d1299bf..161ac76f3d 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
@@ -109,7 +109,14 @@ public class SimpleValueBinder {
     String generator = propertyConfig.getGenerator();
     if (generator != null && simpleValue instanceof BasicValue basicValue) {
       basicValue.setCustomIdGeneratorCreator(
-          context -> createGenerator(property, context, generator));
+          context ->
+              createGenerator(
+                  property,
+                  context.getValue() == null
+                      ? new org.grails.orm.hibernate.cfg.domainbinding.util
+                          .GeneratorCreationContextWrapper(context, basicValue)
+                      : context,
+                  generator));
     }
 
     if (propertyConfig.isDerived() && !(property instanceof TenantId)) {
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/BasicValueIdCreator.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/BasicValueIdCreator.java
index 0a2cb00ab5..04f824b7c5 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/BasicValueIdCreator.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/BasicValueIdCreator.java
@@ -67,7 +67,15 @@ public class BasicValueIdCreator {
     // because table differs)
     String generatorName = Identity.determineGeneratorName(mappedId, 
useSequence);
     id.setCustomIdGeneratorCreator(
-        context -> createGenerator(mappedId, domainClass, context, 
generatorName));
+        context ->
+            createGenerator(
+                mappedId,
+                domainClass,
+                context.getValue() == null
+                    ? new org.grails.orm.hibernate.cfg.domainbinding.util
+                        .GeneratorCreationContextWrapper(context, id)
+                    : context,
+                generatorName));
     return id;
   }
 
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java
index 22a472a499..b84e36be63 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java
@@ -18,13 +18,12 @@
  */
 package org.grails.orm.hibernate.support;
 
-import groovy.lang.Closure;
 import groovy.lang.GroovySystem;
 import groovy.lang.MetaClass;
-import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
 import org.grails.datastore.gorm.GormValidateable;
 import 
org.grails.datastore.gorm.support.BeforeValidateHelper.BeforeValidateEventTriggerCaller;
 import org.grails.datastore.gorm.support.EventTriggerCaller;
@@ -40,9 +39,7 @@ import 
org.grails.orm.hibernate.AbstractHibernateGormValidationApi;
 import org.hibernate.FlushMode;
 import org.hibernate.HibernateException;
 import org.hibernate.Session;
-import org.hibernate.action.internal.EntityUpdateAction;
-import org.hibernate.engine.spi.ActionQueue;
-import org.hibernate.engine.spi.ExecutableList;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
 import org.hibernate.event.spi.*;
 import org.hibernate.jpa.event.spi.CallbackRegistry;
 import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
@@ -51,31 +48,12 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
 import org.hibernate.persister.entity.EntityPersister;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.validation.Errors;
 
-/**
- * Invokes closure events on domain entities such as beforeInsert, 
beforeUpdate and beforeDelete.
- *
- * <p>Also deals with auto time stamping of domain classes that have 
properties named 'lastUpdated'
- * and/or 'dateCreated'.
- *
- * @author Lari Hotari
- * @author Graeme Rocher
- * @since 1.3.5
- */
-@SuppressWarnings({
-  "rawtypes",
-  "unchecked",
-  "serial",
-  "PMD.AvoidAccessibilityAlteration",
-  "PMD.DataflowAnomalyAnalysis",
-  "PMD.CompareObjectsWithEquals",
-  "PMD.CloseResource"
-})
+@SuppressWarnings({"rawtypes", "unchecked", "serial"})
 public class ClosureEventListener
     implements PreLoadEventListener,
         PostLoadEventListener,
+        PreInsertEventListener, // Added to fix "does not exist in superclass" 
error
         PostInsertEventListener,
         PostUpdateEventListener,
         PostDeleteEventListener,
@@ -86,11 +64,8 @@ public class ClosureEventListener
         CallbackRegistryConsumer {
 
   private static final long serialVersionUID = 1;
-
-  /** The log. */
   protected static final Logger LOG = 
LoggerFactory.getLogger(ClosureEventListener.class);
 
-  private final EventTriggerCaller saveOrUpdateCaller;
   private final EventTriggerCaller beforeInsertCaller;
   private final EventTriggerCaller preLoadEventCaller;
   private final EventTriggerCaller postLoadEventListener;
@@ -102,30 +77,22 @@ public class ClosureEventListener
   private final BeforeValidateEventTriggerCaller beforeValidateEventListener;
   private final PersistentEntity persistentEntity;
   private final MetaClass domainMetaClass;
-  private final boolean isMultiTenant;
   private final boolean failOnErrorEnabled;
   private final Map validateParams;
 
-  private Field actionQueueUpdatesField;
-  private Field entityUpdateActionStateField;
-
-  /** Creates a new {@link ClosureEventListener} instance. */
   public ClosureEventListener(
       PersistentEntity persistentEntity, boolean failOnError, List 
failOnErrorPackages) {
     this.persistentEntity = persistentEntity;
     Class domainClazz = persistentEntity.getJavaClass();
     this.domainMetaClass = 
GroovySystem.getMetaClassRegistry().getMetaClass(domainClazz);
-    this.isMultiTenant = ClassUtils.isMultiTenant(domainClazz);
-    saveOrUpdateCaller = buildCaller(AbstractPersistenceEvent.ONLOAD_SAVE, 
domainClazz);
+
     beforeInsertCaller = 
buildCaller(AbstractPersistenceEvent.BEFORE_INSERT_EVENT, domainClazz);
-    EventTriggerCaller preLoadEventCaller =
+    EventTriggerCaller preLoadCaller =
         buildCaller(AbstractPersistenceEvent.ONLOAD_EVENT, domainClazz);
-    if (preLoadEventCaller == null) {
-      this.preLoadEventCaller =
-          buildCaller(AbstractPersistenceEvent.BEFORE_LOAD_EVENT, domainClazz);
-    } else {
-      this.preLoadEventCaller = preLoadEventCaller;
-    }
+    this.preLoadEventCaller =
+        (preLoadCaller != null)
+            ? preLoadCaller
+            : buildCaller(AbstractPersistenceEvent.BEFORE_LOAD_EVENT, 
domainClazz);
 
     postLoadEventListener = 
buildCaller(AbstractPersistenceEvent.AFTER_LOAD_EVENT, domainClazz);
     postInsertEventListener = 
buildCaller(AbstractPersistenceEvent.AFTER_INSERT_EVENT, domainClazz);
@@ -136,199 +103,136 @@ public class ClosureEventListener
 
     beforeValidateEventListener =
         new BeforeValidateEventTriggerCaller(domainClazz, domainMetaClass);
-
-    if (failOnErrorPackages.size() > 0) {
-      failOnErrorEnabled = ClassUtils.isClassBelowPackage(domainClazz, 
failOnErrorPackages);
-    } else {
-      failOnErrorEnabled = failOnError;
-    }
+    failOnErrorEnabled =
+        !failOnErrorPackages.isEmpty()
+            ? ClassUtils.isClassBelowPackage(domainClazz, failOnErrorPackages)
+            : failOnError;
 
     validateParams = new HashMap();
     
validateParams.put(AbstractHibernateGormValidationApi.ARGUMENT_DEEP_VALIDATE, 
Boolean.FALSE);
+  }
 
-    try {
-      actionQueueUpdatesField = ReflectionUtils.findField(ActionQueue.class, 
"updates");
-      actionQueueUpdatesField.setAccessible(true);
-      entityUpdateActionStateField = 
ReflectionUtils.findField(EntityUpdateAction.class, "state");
-      entityUpdateActionStateField.setAccessible(true);
-    } catch (Exception ignored) {
-      // ignore
+  @Override
+  public void onPreLoad(PreLoadEvent event) {
+    if (preLoadEventCaller != null) {
+      doPreLoadWithManualSession(event, () -> 
preLoadEventCaller.call(event.getEntity()));
     }
   }
 
-  //    public void onSaveOrUpdate(SaveOrUpdateEvent event) throws 
HibernateException {
-  //        // no-op, merely a hook for plugins to override
-  //    }
-
-  public void onPreLoad(final PreLoadEvent event) {
-    if (preLoadEventCaller == null) {
-      return;
+  @Override
+  public void onPostLoad(PostLoadEvent event) {
+    if (postLoadEventListener != null) {
+      doPostLoadWithManualSession(event, () -> 
postLoadEventListener.call(event.getEntity()));
     }
+  }
 
-    doWithManualSession(
+  @Override
+  public boolean onPreInsert(PreInsertEvent event) {
+    return doBooleanWithManualSession(
         event,
-        new Closure(this) {
-          @Override
-          public Object call() {
-            preLoadEventCaller.call(event.getEntity());
-            return null;
+        () -> {
+          Object entity = event.getEntity();
+          if (beforeInsertCaller != null) {
+            if (beforeInsertCaller.call(entity)) return true;
+            synchronizePersisterState(event, event.getState());
           }
+          return doValidate(entity);
         });
   }
 
-  public void onPostLoad(final PostLoadEvent event) {
-    if (postLoadEventListener == null) {
-      return;
-    }
+  // --- Specific manual session versions for PreLoad and PostLoad ---
 
-    doWithManualSession(
-        event,
-        new Closure(this) {
-          @Override
-          public Object call() {
-            postLoadEventListener.call(event.getEntity());
-            return null;
-          }
-        });
+  private void doPreLoadWithManualSession(PreLoadEvent event, Runnable action) 
{
+    SharedSessionContractImplementor sessionImpl = event.getSession();
+    if (sessionImpl instanceof Session session) {
+      FlushMode current = session.getHibernateFlushMode();
+      try {
+        session.setHibernateFlushMode(FlushMode.MANUAL);
+        action.run();
+      } finally {
+        session.setHibernateFlushMode(current);
+      }
+    } else {
+      action.run();
+    }
   }
 
-  public void onPostInsert(PostInsertEvent event) {
-    final Object entity = event.getEntity();
-    if (postInsertEventListener == null) {
-      return;
+  private void doPostLoadWithManualSession(PostLoadEvent event, Runnable 
action) {
+    SharedSessionContractImplementor sessionImpl = event.getSession();
+    if (sessionImpl instanceof Session session) {
+      FlushMode current = session.getHibernateFlushMode();
+      try {
+        session.setHibernateFlushMode(FlushMode.MANUAL);
+        action.run();
+      } finally {
+        session.setHibernateFlushMode(current);
+      }
+    } else {
+      action.run();
     }
-
-    doWithManualSession(
-        event,
-        new Closure(this) {
-          @Override
-          public Object call() {
-            postInsertEventListener.call(entity);
-            return null;
-          }
-        });
   }
 
-  //    @Override
-  //    public boolean requiresPostCommitHanding(EntityPersister persister) {
-  //        return false;
-  //    }
+  // --- Standard Overrides ---
 
   @Override
-  public boolean requiresPostCommitHandling(EntityPersister persister) {
-    return false;
+  public void onPostInsert(PostInsertEvent event) {
+    if (postInsertEventListener != null) {
+      doVoidWithManualSession(event, () -> 
postInsertEventListener.call(event.getEntity()));
+    }
   }
 
+  @Override
   public void onPostUpdate(PostUpdateEvent event) {
-    final Object entity = event.getEntity();
-    if (postUpdateEventListener == null) {
-      return;
+    if (postUpdateEventListener != null) {
+      doVoidWithManualSession(event, () -> 
postUpdateEventListener.call(event.getEntity()));
     }
-
-    doWithManualSession(
-        event,
-        new Closure(this) {
-          @Override
-          public Object call() {
-            postUpdateEventListener.call(entity);
-            return null;
-          }
-        });
   }
 
+  @Override
   public void onPostDelete(PostDeleteEvent event) {
-    final Object entity = event.getEntity();
-    if (postDeleteEventListener == null) {
-      return;
+    if (postDeleteEventListener != null) {
+      doVoidWithManualSession(event, () -> 
postDeleteEventListener.call(event.getEntity()));
     }
-
-    doWithManualSession(
-        event,
-        new Closure(this) {
-          @Override
-          public Object call() {
-            postDeleteEventListener.call(entity);
-            return null;
-          }
-        });
   }
 
-  public boolean onPreDelete(final PreDeleteEvent event) {
-    if (preDeleteEventListener == null) {
-      return false;
-    }
-
-    return doWithManualSession(
-        event,
-        new Closure<Boolean>(this) {
-          @Override
-          public Boolean call() {
-            return preDeleteEventListener.call(event.getEntity());
-          }
-        });
-  }
-
-  public boolean onPreUpdate(final PreUpdateEvent event) {
-    return doWithManualSession(
-        event,
-        new Closure<Boolean>(this) {
-          @Override
-          public Boolean call() {
-            Object entity = event.getEntity();
-            boolean evict = false;
-            if (preUpdateEventListener != null) {
-              evict = preUpdateEventListener.call(entity);
-              if (!evict) {
-                synchronizePersisterState(event, event.getState());
-              }
-            }
-            return evict || doValidate(entity);
-          }
-        });
+  @Override
+  public boolean onPreDelete(PreDeleteEvent event) {
+    if (preDeleteEventListener == null) return false;
+    return doBooleanWithManualSession(event, () -> 
preDeleteEventListener.call(event.getEntity()));
   }
 
-  /** On pre insert. */
-  public boolean onPreInsert(final PreInsertEvent event) {
-    return doWithManualSession(
+  @Override
+  public boolean onPreUpdate(PreUpdateEvent event) {
+    return doBooleanWithManualSession(
         event,
-        new Closure<Boolean>(this) {
-          @Override
-          public Boolean call() {
-            Object entity = event.getEntity();
-            boolean synchronizeState = false;
-            if (beforeInsertCaller != null) {
-              if (beforeInsertCaller.call(entity)) {
-                return true;
-              }
-              synchronizeState = true;
-            }
-            if (synchronizeState) {
+        () -> {
+          Object entity = event.getEntity();
+          boolean evict = false;
+          if (preUpdateEventListener != null) {
+            evict = preUpdateEventListener.call(entity);
+            if (!evict) {
               synchronizePersisterState(event, event.getState());
             }
-            return doValidate(entity);
           }
+          return evict || doValidate(entity);
         });
   }
 
-  /** On validate. */
   public void onValidate(ValidationEvent event) {
     beforeValidateEventListener.call(event.getEntityObject(), 
event.getValidatedFields());
   }
 
-  /** Do validate. */
   protected boolean doValidate(Object entity) {
-    boolean evict = false;
     GormValidateable validateable = (GormValidateable) entity;
     if (!validateable.shouldSkipValidation() && 
!validateable.validate(validateParams)) {
-      evict = true;
       if (failOnErrorEnabled) {
-        Errors errors = validateable.getErrors();
         throw ValidationException.newInstance(
             "Validation error whilst flushing entity [" + 
entity.getClass().getName() + "]",
-            errors);
+            validateable.getErrors());
       }
+      return true;
     }
-    return evict;
+    return false;
   }
 
   private EventTriggerCaller buildCaller(String eventName, Class<?> 
domainClazz) {
@@ -337,96 +241,70 @@ public class ClosureEventListener
 
   private void synchronizePersisterState(AbstractPreDatabaseOperationEvent 
event, Object[] state) {
     EntityPersister persister = event.getPersister();
-    synchronizePersisterState(event, state, persister, 
persister.getPropertyNames());
-  }
-
-  private void synchronizePersisterState(
-      AbstractPreDatabaseOperationEvent event,
-      Object[] state,
-      EntityPersister persister,
-      String[] propertyNames) {
     Object entity = event.getEntity();
     EntityReflector reflector = persistentEntity.getReflector();
-    HashMap<Integer, Object> changedState = new HashMap<>();
     EntityMappingType entityMappingType = persister.getEntityMappingType();
-    for (int i = 0; i < propertyNames.length; i++) {
-      String p = propertyNames[i];
+    String[] propertyNames = persister.getPropertyNames();
+
+    for (String p : propertyNames) {
       AttributeMapping attributeMapping = 
entityMappingType.findAttributeMapping(p);
       if (attributeMapping == null) continue;
-      int index = attributeMapping.getStateArrayPosition();
 
+      int index = attributeMapping.getStateArrayPosition();
       PersistentProperty property = persistentEntity.getPropertyByName(p);
-      if (property == null) {
-        continue;
-      }
-      String propertyName = property.getName();
 
-      if (GormProperties.VERSION.equals(propertyName)) {
-        continue;
+      if (property != null && 
!GormProperties.VERSION.equals(property.getName())) {
+        state[index] = reflector.getProperty(entity, property.getName());
       }
+    }
+  }
 
-      Object value = reflector.getProperty(entity, propertyName);
-      if (state[index] != value) {
-        changedState.put(i, value);
+  private void doVoidWithManualSession(AbstractEvent event, Runnable action) {
+    SharedSessionContractImplementor sessionImpl = event.getSession();
+    if (sessionImpl instanceof Session session) {
+      FlushMode current = session.getHibernateFlushMode();
+      try {
+        session.setHibernateFlushMode(FlushMode.MANUAL);
+        action.run();
+      } finally {
+        session.setHibernateFlushMode(current);
       }
-      state[index] = value;
+    } else {
+      action.run();
     }
-
-    synchronizeEntityUpdateActionState(event, entity, changedState);
   }
 
-  private void synchronizeEntityUpdateActionState(
-      AbstractPreDatabaseOperationEvent event,
-      Object entity,
-      HashMap<Integer, Object> changedState) {
-    if (actionQueueUpdatesField != null
-        && event instanceof PreInsertEvent
-        && changedState.size() > 0) {
+  private boolean doBooleanWithManualSession(AbstractEvent event, 
Callable<Boolean> callable) {
+    SharedSessionContractImplementor sessionImpl = event.getSession();
+    if (sessionImpl instanceof Session session) {
+      FlushMode current = session.getHibernateFlushMode();
       try {
-        ExecutableList<EntityUpdateAction> updates =
-            (ExecutableList<EntityUpdateAction>)
-                
actionQueueUpdatesField.get(event.getSession().getActionQueue());
-        if (updates != null) {
-          for (EntityUpdateAction updateAction : updates) {
-            if (updateAction.getInstance() == entity) {
-              Object[] updateState = (Object[]) 
entityUpdateActionStateField.get(updateAction);
-              if (updateState != null) {
-                for (Map.Entry<Integer, Object> entry : 
changedState.entrySet()) {
-                  updateState[entry.getKey()] = entry.getValue();
-                }
-              }
-            }
-          }
-        }
+        session.setHibernateFlushMode(FlushMode.MANUAL);
+        return callable.call();
       } catch (Exception e) {
-        LOG.warn("Error synchronizing object state with Hibernate: " + 
e.getMessage(), e);
+        throw new HibernateException(e);
+      } finally {
+        session.setHibernateFlushMode(current);
       }
     }
-  }
-
-  private <T> T doWithManualSession(AbstractEvent event, Closure<T> callable) {
-    Session session = event.getSession();
-    FlushMode current = session.getHibernateFlushMode();
     try {
-      session.setHibernateFlushMode(FlushMode.MANUAL);
       return callable.call();
-    } finally {
-      session.setHibernateFlushMode(current);
+    } catch (Exception e) {
+      throw new HibernateException(e);
     }
   }
 
   @Override
-  public void onMerge(MergeEvent event) throws HibernateException {}
+  public void onMerge(MergeEvent event) {}
 
   @Override
-  public void onMerge(MergeEvent event, MergeContext copiedAlready) throws 
HibernateException {}
+  public void onMerge(MergeEvent event, MergeContext copiedAlready) {}
 
   @Override
-  public void onPersist(PersistEvent event) throws HibernateException {}
+  public void onPersist(PersistEvent event) {}
 
   @Override
-  public void onPersist(PersistEvent event, PersistContext createdAlready)
-      throws HibernateException {}
+  public void onPersist(PersistEvent event, PersistContext createdAlready) {}
 
   @Override
   public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {}
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/HibernateDialectDetectorFactoryBean.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/HibernateDialectDetectorFactoryBean.java
index 31ce6ad026..4ca7317583 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/HibernateDialectDetectorFactoryBean.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/HibernateDialectDetectorFactoryBean.java
@@ -193,6 +193,11 @@ public class HibernateDialectDetectorFactoryBean 
implements FactoryBean<String>,
           public ServiceRegistry getParentServiceRegistry() {
             return null;
           }
+
+          @Override
+          public boolean isActive() {
+            return true;
+          }
         });
     return factory;
   }
diff --git 
a/grails-data-hibernate7/core/src/main/java/org/grails/orm/hibernate/cfg/domainbinding/util/GeneratorCreationContextWrapper.java
 
b/grails-data-hibernate7/core/src/main/java/org/grails/orm/hibernate/cfg/domainbinding/util/GeneratorCreationContextWrapper.java
new file mode 100644
index 0000000000..3f63b0cd4b
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/main/java/org/grails/orm/hibernate/cfg/domainbinding/util/GeneratorCreationContextWrapper.java
@@ -0,0 +1,93 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.cfg.domainbinding.util;
+
+import org.hibernate.boot.model.relational.Database;
+import org.hibernate.boot.model.relational.SqlStringGenerationContext;
+import org.hibernate.generator.GeneratorCreationContext;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.Value;
+import org.hibernate.service.ServiceRegistry;
+import org.hibernate.type.Type;
+
+/**
+ * A wrapper for {@link GeneratorCreationContext} that allows overriding the 
{@link Value}.
+ */
+public class GeneratorCreationContextWrapper implements 
GeneratorCreationContext {
+
+  private final GeneratorCreationContext delegate;
+  private final Value value;
+
+  public GeneratorCreationContextWrapper(GeneratorCreationContext delegate, 
Value value) {
+    this.delegate = delegate;
+    this.value = value;
+  }
+
+  @Override
+  public Database getDatabase() {
+    return delegate.getDatabase();
+  }
+
+  @Override
+  public ServiceRegistry getServiceRegistry() {
+    return delegate.getServiceRegistry();
+  }
+
+  @Override
+  public String getDefaultCatalog() {
+    return delegate.getDefaultCatalog();
+  }
+
+  @Override
+  public String getDefaultSchema() {
+    return delegate.getDefaultSchema();
+  }
+
+  @Override
+  public PersistentClass getPersistentClass() {
+    return delegate.getPersistentClass();
+  }
+
+  @Override
+  public RootClass getRootClass() {
+    return delegate.getRootClass();
+  }
+
+  @Override
+  public Property getProperty() {
+    return delegate.getProperty();
+  }
+
+  @Override
+  public Value getValue() {
+    return value != null ? value : delegate.getValue();
+  }
+
+  @Override
+  public Type getType() {
+    return delegate.getType();
+  }
+
+  @Override
+  public SqlStringGenerationContext getSqlStringGenerationContext() {
+    return delegate.getSqlStringGenerationContext();
+  }
+}
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreatorSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreatorSpec.groovy
index 4ea6994586..4841c69f40 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreatorSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/BasicValueIdCreatorSpec.groovy
@@ -57,7 +57,7 @@ class BasicValueIdCreatorSpec extends 
HibernateGormDatastoreSpec {
         Generator generator = generatorCreator.createGenerator(context)
 
         then:
-        1 * grailsSequenceWrapper.getGenerator(generatorName, context, 
mappedId, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
+        1 * grailsSequenceWrapper.getGenerator(generatorName, _, mappedId, 
domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
         generator == mockGenerator
 
         where:
@@ -86,7 +86,7 @@ class BasicValueIdCreatorSpec extends 
HibernateGormDatastoreSpec {
         Generator generator = generatorCreator.createGenerator(context)
 
         then:
-        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.NATIVE.toString(),
 context, null, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
+        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.NATIVE.toString(),
 _, null, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
         generator == mockGenerator
     }
 
@@ -102,7 +102,7 @@ class BasicValueIdCreatorSpec extends 
HibernateGormDatastoreSpec {
         Generator generator = generatorCreator.createGenerator(context)
 
         then:
-        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.SEQUENCE_IDENTITY.toString(),
 context, null, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
+        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.SEQUENCE_IDENTITY.toString(),
 _, null, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
         generator == mockGenerator
     }
 
@@ -120,7 +120,7 @@ class BasicValueIdCreatorSpec extends 
HibernateGormDatastoreSpec {
         Generator generator = generatorCreator.createGenerator(context)
 
         then:
-        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.SEQUENCE_IDENTITY.toString(),
 context, mappedId, domainClass, jdbcEnvironment, namingStrategy) >> 
mockGenerator
+        1 * 
grailsSequenceWrapper.getGenerator(GrailsSequenceGeneratorEnum.SEQUENCE_IDENTITY.toString(),
 _, mappedId, domainClass, jdbcEnvironment, namingStrategy) >> mockGenerator
         generator == mockGenerator
     }
 
@@ -137,6 +137,6 @@ class BasicValueIdCreatorSpec extends 
HibernateGormDatastoreSpec {
         generatorCreator.createGenerator(context)
 
         then:
-        1 * grailsSequenceWrapper.getGenerator("custom", context, mappedId, 
domainClass, jdbcEnvironment, namingStrategy) >> Mock(Generator)
+        1 * grailsSequenceWrapper.getGenerator("custom", _, mappedId, 
domainClass, jdbcEnvironment, namingStrategy) >> Mock(Generator)
     }
 }
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/generator/GrailsSequenceGeneratorEnumSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/generator/GrailsSequenceGeneratorEnumSpec.groovy
index 0bf222974e..69fa1fe0a5 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/generator/GrailsSequenceGeneratorEnumSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/generator/GrailsSequenceGeneratorEnumSpec.groovy
@@ -23,7 +23,7 @@ import spock.lang.Shared
 import spock.lang.Unroll
 
 @Testcontainers
-@Requires({ HibernateGormDatastoreSpec.isDockerAvailable() })
+@Requires({ isDockerAvailable() })
 class GrailsSequenceGeneratorEnumSpec extends HibernateGormDatastoreSpec {
 
     @Shared PostgreSQLContainer postgres = new 
PostgreSQLContainer("postgres:16")
@@ -52,9 +52,11 @@ class GrailsSequenceGeneratorEnumSpec extends 
HibernateGormDatastoreSpec {
         // Use the real PostgreSQL database from the running datastore so DDL 
type
         // registries (needed by TableGenerator.registerExportables) are 
correct.
         def db = datastore.metadata.database
+        def table = new 
org.hibernate.mapping.Table("grails_sequence_generator_enum_spec_entity")
         def column = new Column("id")
         def value = Mock(Value) {
             getColumns() >> [column]
+            getTable()   >> table
         }
         def property = Mock(Property) {
             getName() >> "id"
@@ -67,6 +69,7 @@ class GrailsSequenceGeneratorEnumSpec extends 
HibernateGormDatastoreSpec {
             getServiceRegistry() >> serviceRegistry
             getDatabase()        >> db
             getProperty()        >> property
+            getValue()           >> value
             getType()            >> type
         }
     }

Reply via email to