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/03/01 18:09:37 UTC

(grails-core) branch 8.0.x-hibernate7 updated (4b13270674 -> 31123d8c7d)

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

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


    from 4b13270674 refactor more MultiTenantFilterBinder
     new 5cc4dcac05 refactor Mapping calss
     new 31123d8c7d refactor strategy Mapping

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 grails-data-hibernate7/COMPILE-STATIC-AUDIT.md     |  138 ---
 grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md  |  214 ----
 .../HIBERNATE7-GRAILS8-UPGRADE.md                  |  161 ----
 grails-data-hibernate7/PMD.md                      |  128 ---
 grails-data-hibernate7/README.md                   |    8 +-
 grails-data-hibernate7/STATUS.md                   |  112 ---
 grails-data-hibernate7/UPGRADE.md                  | 1019 --------------------
 grails-data-hibernate7/build-full.csv              |  415 --------
 .../org/grails/orm/hibernate/cfg/Mapping.groovy    |    8 +
 .../cfg/domainbinding/binder/ColumnBinder.java     |    8 -
 .../cfg/domainbinding/binder/IndexBinder.java      |    9 +-
 .../cfg/domainbinding/binder/RootBinder.java       |    4 +-
 .../cfg/domainbinding/binder/SubClassBinder.java   |   15 +-
 .../binder/SubclassMappingBinder.java              |   10 +-
 .../hibernate/GrailsHibernatePersistentEntity.java |   29 +-
 .../cfg/domainbinding/binder/RootBinderSpec.groovy |    4 +-
 .../domainbinding/binder/SubClassBinderSpec.groovy |   10 +-
 .../binder/SubclassMappingBinderSpec.groovy        |   76 +-
 18 files changed, 111 insertions(+), 2257 deletions(-)
 delete mode 100644 grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
 delete mode 100644 grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md
 delete mode 100644 grails-data-hibernate7/HIBERNATE7-GRAILS8-UPGRADE.md
 delete mode 100644 grails-data-hibernate7/PMD.md
 delete mode 100644 grails-data-hibernate7/STATUS.md
 delete mode 100644 grails-data-hibernate7/UPGRADE.md
 delete mode 100644 grails-data-hibernate7/build-full.csv


(grails-core) 01/02: refactor Mapping calss

Posted by bo...@apache.org.
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 5cc4dcac05fde8898038231b72aca6808d0cc4c0
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sat Feb 28 21:59:12 2026 -0600

    refactor Mapping calss
---
 .../groovy/org/grails/orm/hibernate/cfg/Mapping.groovy   | 12 ++++++++++++
 .../hibernate/cfg/domainbinding/binder/ColumnBinder.java | 11 +----------
 .../cfg/domainbinding/binder/SubClassBinder.java         |  9 +--------
 .../cfg/domainbinding/binder/SubclassMappingBinder.java  |  4 ++--
 .../hibernate/GrailsHibernatePersistentEntity.java       | 16 ++++++++++------
 5 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
index 897a358724..b250a2c714 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
@@ -140,6 +140,18 @@ class Mapping extends Entity<PropertyConfig> {
     String comment
 
 
+    boolean isTablePerHierarchy() {
+        return tablePerHierarchy
+    }
+
+    boolean isJoinedSubclass() {
+        return !tablePerHierarchy && !tablePerConcreteClass
+    }
+
+    boolean isUnionSubclass() {
+        return tablePerConcreteClass
+    }
+
     boolean isTablePerConcreteClass() {
         return tablePerConcreteClass
     }
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
index 29cb7402aa..4a5a055603 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
@@ -76,14 +76,6 @@ public class ColumnBinder {
         new IndexBinder());
   }
 
-  /** Protected constructor for testing purposes. */
-  protected ColumnBinder() {
-    this.columnNameForPropertyAndPathFetcher = null;
-    this.stringColumnConstraintsBinder = null;
-    this.numericColumnConstraintsBinder = null;
-    this.createKeyForProps = null;
-    this.indexBinder = null;
-  }
 
   /**
    * Binds a Column instance to the Hibernate meta model
@@ -154,8 +146,7 @@ public class ColumnBinder {
 
     var owner = property.getHibernateOwner();
     if (!owner.isRoot()) {
-      Mapping mapping = owner.getMappedForm();
-      if (mapping != null && mapping.getTablePerHierarchy()) {
+      if (owner.isTablePerHierarchy()) {
         if (LOG.isDebugEnabled())
           LOG.debug(
               "[GrailsDomainBinder] Sub class property ["
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
index b1049a5e4b..f73424b2c5 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
@@ -65,17 +65,10 @@ public class SubClassBinder {
       Mapping m) {
     mappingCacheHolder.cacheMapping(sub);
     Subclass subClass = subclassMappingBinder.createSubclassMapping(sub, parent, mappings, m);
-
     parent.addSubclass(subClass);
     mappings.addEntityBinding(subClass);
-
     bindMultiTenantFilter(sub, subClass);
-
-    Collection<GrailsHibernatePersistentEntity> children = sub.getChildEntities(dataSourceName);
-    if (!children.isEmpty()) {
-      // bind the sub classes
-      children.forEach(sub1 -> bindSubClass(sub1, subClass, mappings, m));
-    }
+    sub.getChildEntities(dataSourceName).forEach(sub1 -> bindSubClass(sub1, subClass, mappings, m));
   }
 
   private void bindMultiTenantFilter(GrailsHibernatePersistentEntity sub, Subclass subClass) {
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
index ade61515b2..08dc1fa15d 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
@@ -59,11 +59,11 @@ public class SubclassMappingBinder {
       Mapping m) {
     Subclass subClass;
     subEntity.configureDerivedProperties();
-    if (!m.getTablePerHierarchy() && !m.isTablePerConcreteClass()) {
+    if (m.isJoinedSubclass()) {
       var joined = new JoinedSubclass(parent, this.metadataBuildingContext);
       joinedSubClassBinder.bindJoinedSubClass(subEntity, joined, mappings);
       subClass = joined;
-    } else if (m.isTablePerConcreteClass()) {
+    } else if (m.isUnionSubclass()) {
       var union = new UnionSubclass(parent, this.metadataBuildingContext);
       unionSubclassBinder.bindUnionSubclass(subEntity, union, mappings);
       subClass = union;
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
index 17409f1c39..3911799126 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
@@ -55,21 +55,25 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
 
   default boolean isTablePerHierarchy() {
     Mapping mapping = getMappedForm();
-    return mapping == null || mapping.getTablePerHierarchy();
+    return mapping == null || mapping.isTablePerHierarchy();
   }
 
-  default boolean isTablePerConcreteClass() {
+  default boolean isJoinedSubclass() {
     Mapping mapping = getMappedForm();
-    return mapping != null && mapping.isTablePerConcreteClass();
+    return mapping != null && mapping.isJoinedSubclass();
+  }
+
+  default boolean isUnionSubclass() {
+    Mapping mapping = getMappedForm();
+    return mapping != null && mapping.isUnionSubclass();
   }
 
   default boolean isTableAbstract() {
-    return !isTablePerHierarchy() && isTablePerConcreteClass() && isAbstract();
+    return isUnionSubclass() && isAbstract();
   }
 
   default boolean isTablePerHierarchySubclass() {
-    Mapping rootMapping = getRootMapping();
-    return !this.isRoot() && (rootMapping == null || rootMapping.getTablePerHierarchy());
+    return !this.isRoot() && getHibernateRootEntity().isTablePerHierarchy();
   }
 
   default Set<String> buildDiscriminatorSet() {


(grails-core) 02/02: refactor strategy Mapping

Posted by bo...@apache.org.
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 31123d8c7d3bdc62d8aae36b078ae54c334bf0b0
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sun Mar 1 00:09:59 2026 -0600

    refactor strategy Mapping
---
 grails-data-hibernate7/COMPILE-STATIC-AUDIT.md     |  138 ---
 grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md  |  214 ----
 .../HIBERNATE7-GRAILS8-UPGRADE.md                  |  161 ----
 grails-data-hibernate7/PMD.md                      |  128 ---
 grails-data-hibernate7/README.md                   |    8 +-
 grails-data-hibernate7/STATUS.md                   |  112 ---
 grails-data-hibernate7/UPGRADE.md                  | 1019 --------------------
 grails-data-hibernate7/build-full.csv              |  415 --------
 .../org/grails/orm/hibernate/cfg/Mapping.groovy    |    4 -
 .../cfg/domainbinding/binder/ColumnBinder.java     |    3 +-
 .../cfg/domainbinding/binder/IndexBinder.java      |    9 +-
 .../cfg/domainbinding/binder/RootBinder.java       |    4 +-
 .../cfg/domainbinding/binder/SubClassBinder.java   |    8 +-
 .../binder/SubclassMappingBinder.java              |   10 +-
 .../hibernate/GrailsHibernatePersistentEntity.java |   17 +-
 .../cfg/domainbinding/binder/RootBinderSpec.groovy |    4 +-
 .../domainbinding/binder/SubClassBinderSpec.groovy |   10 +-
 .../binder/SubclassMappingBinderSpec.groovy        |   76 +-
 18 files changed, 97 insertions(+), 2243 deletions(-)

diff --git a/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md b/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
deleted file mode 100644
index 51b4cdfb4f..0000000000
--- a/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
+++ /dev/null
@@ -1,138 +0,0 @@
-# `@CompileStatic` Eligibility Audit — `grails-data-hibernate7`
-
-All `.groovy` files under `src/main` across all four submodules (`core`, `boot-plugin`, `grails-plugin`, `dbmigration`).
-
-Legend:
-- ✅ **Done** — `@CompileStatic` at class level, no workarounds needed
-- ⚠️ **Partial** — class-level `@CompileStatic` present but some methods still carry `@CompileDynamic`
-- ❌ **Not Eligible** — dynamic dispatch is inherent; cannot be made static
-
----
-
-## `core` submodule
-
-### Config / Model classes
-
-| File | Status | Notes |
-|------|--------|-------|
-| `cfg/CacheConfig.groovy` | ✅ Done | |
-| `cfg/ColumnConfig.groovy` | ✅ Done | |
-| `cfg/CompositeIdentity.groovy` | ✅ Done | |
-| `cfg/DiscriminatorConfig.groovy` | ✅ Done | |
-| `cfg/Identity.groovy` | ✅ Done | |
-| `cfg/InstanceProxy.groovy` | ✅ Done | |
-| `cfg/JoinTable.groovy` | ✅ Done | |
-| `cfg/NaturalId.groovy` | ✅ Done | |
-| `cfg/PropertyConfig.groovy` | ✅ Done | |
-| `cfg/PropertyDefinitionDelegate.groovy` | ✅ Done | |
-| `cfg/SortConfig.groovy` | ✅ Done | |
-| `cfg/Table.groovy` | ✅ Done | |
-| `cfg/Mapping.groovy` | ✅ Done | `methodMissing` is required for DSL property-name dispatch (domain field names are unknown at compile time). `@CompileDynamic` on method body removed — replaced `args[-1]` (Groovy negative array index) with `argsArray[argsArray.length - 1]`; cast `args` to `Object[]` explicitly. `@CompileDynamic` import removed. Verified by `MappingSpec` (5 new `methodMissing` tests + 8 existing = 13/13 pass). |
-
-### DSL / Mapping builder
-
-| File | Status | Notes |
-|------|--------|-------|
-| `cfg/domainbinding/hibernate/HibernateMappingBuilder.groovy` | ✅ Done | Full `@CompileStatic` rewrite; `methodMissing` is `def` (required Groovy hook) |
-| `cfg/domainbinding/hibernate/HibernateMappingFactory.groovy` | ✅ Done | |
-| `cfg/domainbinding/hibernate/GrailsJpaMappingConfigurationStrategy.groovy` | ✅ Done | |
-| `cfg/domainbinding/generator/GrailsSequenceGeneratorEnum.groovy` | ✅ Done | `@CompileStatic` added; spec rewritten to extend `HibernateGormDatastoreSpec` + Postgres Testcontainer (replaces `GroovyMock(global:true)`) |
-
-### GORM APIs
-
-| File | Status | Notes |
-|------|--------|-------|
-| `HibernateGormEnhancer.groovy` | ✅ Done | |
-| `HibernateGormValidationApi.groovy` | ✅ Done | |
-| `AbstractHibernateGormValidationApi.groovy` | ✅ Done | |
-| `HibernateGormInstanceApi.groovy` | ✅ Done | `isDirty`/`findDirty`/`getDirtyPropertyNames` correctly typed. `nextId()` removed (dead code). `incrementVersion` — `GroovyObject` cast + `metaClass.hasProperty`/`getProperty`/`setProperty`. `setErrorsOnInstance` — `GroovyObject.setProperty` replaces dynamic property write. `runDeferredBinding` — reflection (`Class.getMethod('runActions').invoke(null)`); `@CompileDynamic` not needed because `DeferredBindingActions` belongs to the migration p [...]
-| `HibernateGormStaticApi.groovy` | ✅ Done | `findWithSql`/`findAllWithSql` deprecated in favour of `findWithNativeSql`/`findAllWithNativeSql`. `getAllInternal` fully typed. |
-
-### Infrastructure
-
-| File | Status | Notes |
-|------|--------|-------|
-| `GrailsHibernateTransactionManager.groovy` | ✅ Done | |
-| `MetadataIntegrator.groovy` | ✅ Done | |
-| `HibernateEntity.groovy` | ✅ Done | `findWithSql`/`findAllWithSql` `@Deprecated` and delegating to `findWithNativeSql`/`findAllWithNativeSql`; all new methods `@Generated` |
-| `mapping/MappingBuilder.groovy` | ✅ Done | |
-| `compiler/HibernateEntityTransformation.groovy` | ✅ Done | |
-| `connections/HibernateConnectionSourceSettings.groovy` | ✅ Done | |
-| `connections/HibernateConnectionSourceSettingsBuilder.groovy` | ✅ Done | |
-| `dirty/GrailsEntityDirtinessStrategy.groovy` | ✅ Done | Stale `@CompileDynamic` removed from `getStatus`; typed `EntityEntry`, explicit null check |
-| `support/HibernateDatastoreConnectionSourcesRegistrar.groovy` | ✅ Done | |
-| `support/HibernateDatastoreFactoryBean.groovy` | ✅ Done | |
-| `support/HibernateRuntimeUtils.groovy` | ✅ Done | |
-| `support/DataSourceFactoryBean.groovy` | ✅ Done | `@CompileStatic` added |
-
----
-
-## `boot-plugin` submodule
-
-| File | Status | Notes |
-|------|--------|-------|
-| `HibernateGormAutoConfiguration.groovy` | ✅ Done | |
-| `GormCompilerAutoConfiguration.groovy` | ✅ Done | |
-
----
-
-## `grails-plugin` submodule
-
-| File | Status | Notes |
-|------|--------|-------|
-| `HibernateDatastoreSpringInitializer.groovy` | ✅ Done | |
-| `HibernateGrailsPlugin.groovy` | ✅ Done | |
-| `commands/SchemaExportCommand.groovy` | ✅ Done | |
-| `HibernateSpec.groovy` | ✅ Done | |
-
----
-
-## `dbmigration` submodule
-
-| File | Status | Notes |
-|------|--------|-------|
-| `DatabaseMigrationException.groovy` | ✅ Done | `@CompileStatic` added |
-| `PluginConstants.groovy` | ✅ Done | `@CompileStatic` added |
-| `NoopVisitor.groovy` | ✅ Done | `@CompileStatic` added |
-| `DatabaseMigrationTransactionManager.groovy` | ❌ Not Eligible | Dynamic `Map` property assignment on `DefaultTransactionDefinition`. Inherently dynamic. |
-| `DatabaseMigrationGrailsPlugin.groovy` | ❌ Not Eligible | Grails plugin DSL (`doWithSpring`, `doWithApplicationContext`). Inherently dynamic. |
-| `EnvironmentAwareCodeGenConfig.groovy` | ⚠️ Partial | `mergeEnvironmentConfig` uses `.environments?."$environment"` (dynamic GPath). Cannot be made static. |
-| `command/DatabaseMigrationCommand.groovy` | ⚠️ Partial | `createDatabase` uses `clazz.decode(password)` via dynamic dispatch on a runtime-loaded codec. Cannot be made static without a typed interface. |
-| `command/ApplicationContextDatabaseMigrationCommand.groovy` | ✅ Done | |
-| `command/DbmChangelogToGroovy.groovy` | ✅ Done | |
-| `command/DbmCreateChangelog.groovy` | ✅ Done | |
-| `command/ScriptDatabaseMigrationCommand.groovy` | ✅ Done | |
-| `liquibase/GrailsLiquibaseFactory.groovy` | ✅ Done | `@CompileStatic` added |
-| `liquibase/GrailsLiquibase.groovy` | ✅ Done | |
-| `liquibase/ChangelogXml2Groovy.groovy` | ✅ Done | |
-| `liquibase/DatabaseChangeLogBuilder.groovy` | ✅ Done | |
-| `liquibase/EmbeddedJarPathHandler.groovy` | ✅ Done | |
-| `liquibase/GormColumnSnapshotGenerator.groovy` | ✅ Done | |
-| `liquibase/GormDatabase.groovy` | ✅ Done | |
-| `liquibase/GroovyChange.groovy` | ✅ Done | |
-| `liquibase/GroovyChangeLogSerializer.groovy` | ✅ Done | |
-| `liquibase/GroovyDiffToChangeLogCommandStep.groovy` | ✅ Done | |
-| `liquibase/GroovyGenerateChangeLogCommandStep.groovy` | ✅ Done | |
-| `liquibase/GroovyPrecondition.groovy` | ✅ Done | |
-| `liquibase/GroovyChangeLogParser.groovy` | ⚠️ Partial | See §GroovyChangeLogParser detail below |
-
----
-
-## Detailed Analysis of Remaining Partial Files
-
-### `liquibase/GroovyChangeLogParser.groovy`
-
-| Method | Reason dynamic | Can be fixed? |
-|--------|---------------|---------------|
-| `parseToNode(...)` | `compilerConfiguration.metaClass.respondsTo(...)` metaClass access | **Possibly** — guard can be removed; locals can be typed |
-| `setChangeLogProperties(...)` | `changeLogProperties.each { name, value -> ... }` with dynamic `value.contexts` / `value.labels` on `Object` | **Possibly** — type as `Map<String,Object>`, add `instanceof` guards |
-
----
-
-## Remaining Actions
-
-| Action | File | Effort |
-|--------|------|--------|
-| Remove metaClass guard + type locals in `parseToNode` | `GroovyChangeLogParser.groovy:48` | Medium |
-| Add `instanceof` guards for dynamic map values in `setChangeLogProperties` | `GroovyChangeLogParser.groovy:91` | Medium |
-| Accept as permanently dynamic |  `DatabaseMigrationTransactionManager`, `DatabaseMigrationGrailsPlugin`, `createDatabase` in `DatabaseMigrationCommand`, `mergeEnvironmentConfig` in `EnvironmentAwareCodeGenConfig` | No action |
diff --git a/grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md b/grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md
deleted file mode 100644
index d2a89e16af..0000000000
--- a/grails-data-hibernate7/GORM-QUERY-SAFETY-AUDIT.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# GORM Query Safety Audit — `grails-data-hibernate7`
-
-> **Scope**: Section 2.6 of `UPGRADE.md`  
-> **Priority**: P2 — SQL injection is OWASP Top-10 #3  
-> **Module**: `grails-data-hibernate7-core`  
-> **Last updated**: 2026-02-23
-
----
-
-## Summary
-
-| Risk Level | Count | Fixed |
-|------------|-------|-------|
-| 🔴 HIGH    | 2     | ✅ 2  |
-| 🟡 MEDIUM  | 3     | ✅ 3  |
-| 🟢 LOW / Safe | 5  | n/a   |
-
----
-
-## 🔴 HIGH — Real Injection Vectors
-
-### H-1 · `DefaultSchemaHandler` — Schema Name Spliced Raw into DDL ✅ FIXED
-
-| Field | Value |
-|-------|-------|
-| **File** | `grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/jdbc/schema/DefaultSchemaHandler.groovy` |
-| **Lines** | 57–77 (original) |
-
-**Original code**:
-```groovy
-connection.createStatement().execute(String.format("SET SCHEMA %s", name))
-connection.createStatement().execute(String.format("CREATE SCHEMA %s", name))
-```
-
-Schema names come from `TenantResolver` (user-controlled in schema-per-tenant multitenancy). JDBC parameter binding is not possible for DDL identifiers, making this a real injection vector.
-
-**Fix applied**: Added `quoteName(Connection, String)` using `connection.metaData.identifierQuoteString`. The name is stripped of embedded quote characters before wrapping, preventing breakout. Falls through to unquoted if the driver reports quoting unsupported (returns `" "`).
-
-```groovy
-protected static String quoteName(Connection connection, String name) {
-    String q = connection.metaData.identifierQuoteString ?: ''
-    if (!q || q.trim().isEmpty()) return name
-    String safe = name.replace(q, '')
-    return "${q}${safe}${q}"
-}
-```
-
-**Verified by**: `DefaultSchemaHandlerSpec` — 9 tests passing (quoting, injection stripping, unsupported-quoting fallthrough, `useSchema`, `createSchema`, `useDefaultSchema`, custom template).
-
----
-
-### H-2 · `HibernateGormStaticApi` — Single-Arg Overloads Accept Plain `String` ✅ FIXED
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy` |
-| **Lines** | 233–250 |
-
-**Root cause**: `HibernateHqlQuery.createHqlQuery` converts `GString` interpolations to named parameters but calls `.toString()` on any non-`GString` `CharSequence`, passing it raw to `session.createQuery()`. The four single-arg overloads had no guard — a plain `String` from string concatenation reached Hibernate unchanged.
-
-**Example of unsafe caller pattern** (application code):
-```groovy
-// UNSAFE — plain String, no parameterization
-String q = "from User where name = '" + userInput + "'"
-User.find(q)   // HQL injection possible
-
-// SAFE — GString interpolation is converted to named params by GORM
-User.find("from User where name = ${userInput}")
-
-// SAFE — explicit named params
-User.find("from User where name = :name", [name: userInput])
-```
-
-**Fix applied**: Added `requireGString(CharSequence, String)` guard to all four single-arg overloads. Throws `UnsupportedOperationException` with a descriptive message directing callers to use GString interpolation or the parameterized overloads.
-
-```groovy
-private static void requireGString(CharSequence query, String method) {
-    if (!(query instanceof GString)) {
-        throw new UnsupportedOperationException(
-            "${method}(CharSequence) only accepts a Groovy GString with interpolated parameters " +
-            "(e.g. ${method}(\"from Foo where bar = \${value}\")). " +
-            "Use the parameterized overload ${method}(CharSequence, Map) or " +
-            "${method}(CharSequence, Collection, Map) to pass a plain String query safely."
-        )
-    }
-}
-```
-
-This also subsumes **M-2** (the `executeUpdate` write-path concern) since the guard applies to `executeUpdate(CharSequence)` as well.
-
-**Verified by**: `HibernateGormStaticApiSpec` — 4 new tests confirming `UnsupportedOperationException` for `find`, `findAll`, `executeQuery`, `executeUpdate` with plain `String`; all 41 spec tests pass.
-
----
-
-## 🟡 MEDIUM — Potential Risks Requiring Context
-
-### M-1 · `findWithSql` / `findAllWithSql` — Native SQL Without Enforced Parameterization ✅ FIXED
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy` |
-| **File** | `core/src/main/groovy/grails/orm/hibernate/HibernateEntity.groovy` |
-| **Lines** | 224, 228 (original) |
-| **Status** | ✅ Fixed |
-
-**Root cause**: `findWithSql` / `findAllWithSql` passed any `CharSequence` directly to `session.createNativeQuery()`. Plain `String` from concatenation reached the database unchanged.
-
-**Why `requireGString` was not applied to native SQL**: Unlike HQL (where all values can be bound as named parameters), native SQL identifiers — table names, column names — cannot be parameterized via JDBC. Applying `requireGString` would block legitimate static SQL strings and would also break GString interpolation of identifiers (Hibernate would bind them as `?` positional params, producing malformed SQL like `select * from ? c`).
-
-**Fix applied**:
-1. Renamed to `findWithNativeSql(CharSequence, Map)` / `findAllWithNativeSql(CharSequence, Map)` in both `HibernateGormStaticApi` and `HibernateEntity`. The new name makes the native SQL risk surface explicit at every call site.
-2. Old `findWithSql` / `findAllWithSql` marked `@Deprecated` and delegated to the new names — full backwards compatibility preserved.
-3. GString value parameterization still works (`where c.name like ${p}` → bound as `:p0`); callers must never concatenate user input into the SQL string.
-
-**Safety contract for native SQL** (documented, not enforceable at compile time):
-```groovy
-// ✅ SAFE — static SQL, no user input
-Club.findAllWithNativeSql("select * from club c order by c.name")
-
-// ✅ SAFE — user value as GString interpolation → bound as :p0
-String name = userInput
-Club.findWithNativeSql("select * from club c where c.name = ${name}")
-
-// ❌ UNSAFE — never do this
-Club.findAllWithNativeSql("select * from club where name = '" + userInput + "'")
-```
-
-**Verified by**: `HibernateGormStaticApiSpec` — `test simple sql query`, `test sql query with gstring parameters`, `test deprecated findAllWithSql delegates to findAllWithNativeSql`, `test deprecated findWithSql delegates to findWithNativeSql` all pass (43/43 total).
-
----
-
-### M-2 · `executeUpdate(CharSequence)` Write-Path Risk
-
-| Status | Covered by H-2 fix ✅ |
-|--------|----------------------|
-
-The `executeUpdate(CharSequence)` single-arg overload was the highest-severity instance of H-2 due to the write path. It is now guarded by `requireGString` (see H-2 above).
-
----
-
-### M-3 · `HibernateGormInstanceApi.nextId()` — Dead Code Removed ✅ FIXED
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/HibernateGormInstanceApi.groovy` |
-| **Status** | ✅ Removed — method had no callers; was left over from the Hibernate 5 `GrailsIncrementGenerator` strategy |
-
----
-
-## 🟢 SAFE — Verified Parameterized Paths
-
-### S-1 · `HibernateHqlQuery.buildNamedParameterQueryFromGString` — GString Mitigation (WORKS)
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java` |
-| **Lines** | 97–112, 128–130 |
-
-GString interpolations are converted to named parameters before the query string reaches Hibernate. Each `${value}` becomes `:p0`, `:p1`, etc. and is bound via `setParameter()`. This correctly prevents injection when callers use GString syntax.
-
----
-
-### S-2 · `HibernateSession.deleteAll` / `updateAll` — JPA Criteria Builder (SAFE)
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/HibernateSession.java` |
-| **Lines** | 96–128, 137–179 |
-
-Both methods use `JpaQueryBuilder` to construct parameterized HQL. All values are bound via `query.setParameter(...)`. No user-controlled strings are concatenated into the query.
-
----
-
-### S-3 · `HibernateQuery` / `JpaCriteriaQueryCreator` — JPA Criteria API (SAFE)
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java`, `JpaCriteriaQueryCreator.java` |
-
-Query construction goes through the JPA `CriteriaBuilder` API entirely. Values are passed as typed `ParameterExpression` objects. No string interpolation.
-
----
-
-### S-4 · `HibernateHqlQuery` — `"from " + clazz.getName()` (SAFE)
-
-| Field | Value |
-|-------|-------|
-| **File** | `core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java` |
-| **Line** | 146 |
-
-```java
-q = session.createQuery("from " + clazz.getName(), clazz);
-```
-
-`clazz` is derived from `PersistentEntity.getJavaClass()` — a framework-managed class reference, not user input.
-
----
-
-### S-5 · Dynamic Finders — GORM Criteria API (SAFE by design)
-
-Dynamic finders (`findByName`, `findAllByTitleAndAuthor`, etc.) are translated to typed criteria queries via the GORM query parser. All values arrive as method arguments and are bound as typed parameters. No string interpolation occurs.
-
----
-
-## Action Items for Grails 8
-
-| ID | Action | Target | Status |
-|----|--------|--------|--------|
-| A-1 | Quote schema name in `DefaultSchemaHandler.useSchema` / `createSchema` using JDBC identifier quoting | `DefaultSchemaHandler.groovy` | ✅ Done — `quoteName()` added; `DefaultSchemaHandlerSpec` 9/9 pass |
-| A-2 | Guard `find/findAll/executeQuery/executeUpdate(CharSequence)` single-arg overloads — throw `UnsupportedOperationException` for plain `String` | `HibernateGormStaticApi.groovy` | ✅ Done — `requireGString()` guard; `HibernateGormStaticApiSpec` 43/43 pass |
-| A-3 | ~~Add runtime warning for plain `String` to no-param API~~ | superseded by A-2 (exception is better than warning) | ✅ Superseded |
-| A-4 | Rename `findWithSql` / `findAllWithSql` to `findWithNativeSql` / `findAllWithNativeSql`; deprecate old names | `HibernateGormStaticApi.groovy`, `HibernateEntity.groovy` | ✅ Done — old names `@Deprecated` and delegating; GString value params still work; 43/43 pass |
-| A-5 | Change `nextId()` HQL from GString to plain concatenation | `HibernateGormInstanceApi.groovy:178` | ✅ Done |
-| A-6 | Document safe query patterns in GORM reference guide: prefer named params / criteria API, never concatenate user input into native SQL | `docs/` | ✅ Done — `querying/hql.adoc`, `querying/nativeSql.adoc`, `introduction/upgradeNotes.adoc` written |
diff --git a/grails-data-hibernate7/HIBERNATE7-GRAILS8-UPGRADE.md b/grails-data-hibernate7/HIBERNATE7-GRAILS8-UPGRADE.md
deleted file mode 100644
index 6bf5db52e4..0000000000
--- a/grails-data-hibernate7/HIBERNATE7-GRAILS8-UPGRADE.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# Hibernate 7 / Grails 8 Upgrade Issues
-
-Extracted from the full Grails 8 modernisation roadmap (`UPGRADE.md`), this document covers only the Hibernate-specific issues.
-
----
-
-
----
-
-## 1. Module Consolidation: Remove `grails-data-hibernate6`
-
-The `8.0.x-hibernate7` branch ships three Hibernate modules. Only two should reach GA:
-
-| Module | Hibernate Version | Binder Architecture | Gaps | Ship in Grails 8? |
-|--------|-------------------|---------------------|------|-------------------|
-| `grails-data-hibernate5` | 5.6-jakarta | Monolithic `GrailsDomainBinder` (to be refactored) | None (production) | **Yes** — legacy path |
-| `grails-data-hibernate7` | 7.2 | Fully decomposed `domainbinding/binder/` hierarchy + generators + entity hierarchy | None | **Yes** — modern path |
-
-`grails-data-hibernate7` supersedes all `grails-data-hibernate6` work — the 56 files unique to `hibernate6` are the old binder pattern that `hibernate7` replaced with 176 new files in the decomposed hierarchy.
-- `hibernate6` still has known gaps (multitenancy, proxy support) that `hibernate7` resolved.
-- Maintaining 3 modules instead of 2 triples the surface area for Hibernate API changes.
-
-**Removal plan:**
-3. Verify no other modules reference `grails-data-hibernate6` in their build files.
-
----
-
-## 2. Binder Refactoring (Apply to Both Versions)
-
-The `8.0.x-hibernate7` branch decomposes the monolithic `GrailsDomainBinder` into a proper hierarchy in `grails-data-hibernate7`. **This refactoring must also be applied to `grails-data-hibernate5`.**
-
-**New binder hierarchy in `grails-data-hibernate7`:**
-- `RootBinder`, `SubClassBinder`, `SubclassMappingBinder`, `DiscriminatorPropertyBinder`
-- `ComponentBinder`, `CollectionSecondPassBinder`, `DependentKeyValueBinder`
-- `UnidirectionalOneToManyBinder`, `SimpleValueColumnBinder`, `PrimaryKeyValueCreator`
-- `HibernateCriteriaBuilder` refactored with `CriteriaMethodInvoker` and `CriteriaMethods` enum
-- `GrailsHibernatePersistentEntity` and `GrailsHibernatePersistentProperty` hierarchy enriched
-- Each binder has its own Spock spec (testable in isolation)
-
-Having `grails-data-hibernate5` use a monolithic `GrailsDomainBinder` while `grails-data-hibernate7` has proper binder separation would make long-term maintenance significantly harder.
-
----
-
-## 3. Version Selection Mechanism
-
-Users must be able to choose their Hibernate version at dependency resolution time without classpath conflicts.
-
-**Proposed approach — Maven classifier + Gradle `requireCapability`:**
-
-```groovy
-// Option A: Hibernate 5.6-jakarta (legacy, default for migration)
-implementation 'org.apache.grails:grails-data-hibernate:8.0.0:hibernate56'
-
-// Option B: Hibernate 7.2 (modern, recommended for new projects)
-implementation 'org.apache.grails:grails-data-hibernate:8.0.0:hibernate72'
-```
-
-Or via Gradle feature variants:
-
-```groovy
-dependencies {
-    implementation('org.apache.grails:grails-data-hibernate:8.0.0') {
-        requireCapability 'org.apache.grails:grails-data-hibernate-7.2'
-    }
-}
-```
-
-**Goals:**
-- No classpath conflicts (only one Hibernate version on the classpath at a time).
-- BOM/platform support for transitive Hibernate version alignment.
-- Clear migration path: start with 5.6, switch to 7.2 when ready.
-- Grails Forge can offer the choice at project creation time.
-
----
-
-## 4. Liquibase / Database Migration Plugin Concerns
-
-### Hibernate 5.6 path
-No license issue. The Legacy Database Migration plugin pins to Liquibase 4.27.0 and `liquibase-hibernate5`, both Apache 2.0 licensed. This continues to work as in Grails 7.
-
-### Hibernate 7.2 path
-PR [liquibase/liquibase-hibernate#844](https://github.com/liquibase/liquibase-hibernate/pull/844) Database Migration plugin is for Hibernate 7 support to `liquibase-hibernate`, and it targets Liquibase 4.29.2, , both Apache 2.0 licensed.
-
-
----
-
-## 5. Hibernate Entity Static Trait — Groovy 5 Joint Compilation Failure
-
-**Context:** `HibernateEntity` (in `grails-data-hibernate5-core`) has 5 static methods with generic return types. `HibernateMappingContext.java` in the same module directly imports the trait. Under Groovy 5, the stub generator produces invalid Java:
-
-```java
-// Generated stub (INVALID Java)
-@groovy.transform.Generated()
-static java.util.List<D> findAllWithSql(java.lang.CharSequence sql);
-//                    ^ ERROR: non-static type variable D cannot be
-//                      referenced from static context
-```
-
-In Java, a class-level type parameter (`D`) cannot be referenced from a static method. The Groovy trait works at runtime but the stub generator doesn't account for this.
-
-**Comparison with other traits:**
-
-| Trait | Module | Static Methods | Java Files Import It? | Result in Groovy 5 |
-|-------|--------|----------------|-----------------------|-------------------|
-| `GormEntity` | grails-datamapping-core | 87 | No | Works |
-| `HibernateEntity` | grails-data-hibernate5-core | 5 | **Yes** (`HibernateMappingContext.java`) | **Fails** |
-| `MongoEntity` | grails-data-mongodb | 18 | No | Works |
-
-**Decision options:**
-
-| Approach | Description | Trade-off |
-|----------|-------------|-----------|
-| **Convert Java class to Groovy** | Rewrite `HibernateMappingContext.java` as `.groovy` so it goes through Groovy compilation | Slower Groovy compilation |
-
----
-
-## 6. `HibernateMappingBuilder` — `@CompileStatic` Compatibility (Groovy 5)
-
-`HibernateMappingBuilder` uses `methodMissing` to handle arbitrary domain property names (e.g. `title`, `name`, `dateCreated`). Under Groovy 5, `@CompileStatic` on the class means the compiler cannot see `methodMissing`-dispatched calls as valid. Required changes:
-
-1. **Replace `methodMissing` for common DSL methods with explicit typed methods** — `methodMissing` remains as the generic fallback but typed DSL entrypoints must exist for the compiler.
-2. **Add `@DelegatesTo` to all closure-accepting methods** — allows the Groovy 5 static type checker to validate the DSL body passed by callers.
-3. **`Entity.getSort()` type resolution** — `Entity<P>` declares `Object getSort()` returning `defaultSort`; `Mapping` declares a `SortConfig sort` field. Under `@CompileStatic` in `HibernateMappingBuilder`, `mapping.getSort()` resolves to `Object`. Fix: explicit cast `(SortConfig) mapping.getSort()`.
-4. **`PropertyConfig.typeParams` (`Properties` vs `Map`)** — `typeParams` is typed as `java.util.Properties`; assigning a raw `Map` fails `@CompileStatic`. Use `Properties.put(Object, Object)` (not `setProperty`, which stringifies values and breaks integer-preserving type params).
-5. **`setUnique` overload resolution** — `Property.setUnique` has three overloads: `boolean`, `String` (uniqueness group), and `List<String>`. `@CompileStatic` requires explicit `instanceof` guards for each overload.
-6. **`importFrom` handling** — The `importFrom` constraint keyword (used in `static constraints`) must remain handled in `methodMissing`, delegating to `ClassPropertyFetcher.getStaticPropertyValuesFromInheritanceHierarchy()`. Removing it causes `importFrom` constraints to be silently ignored at mapping time, breaking column-length DDL generation.
-All done in `HibernateMappingBuilder`.
-
----
-
-## 7. Why Hibernate 7 Matters
-
-- **Jakarta Persistence 3.2** compliance (Jakarta EE 11).
-- **Spring Boot 4** ships with Hibernate 7.2 as its default ORM provider.
-- Hibernate 7 drops many deprecated 5.x APIs that GORM currently wraps.
-- Better SQL generation, stateless session improvements, annotation processor support.
-
----
-
-## 8. Recommended Action for `grails-data-hibernate7`
-
-Do **not** drop Hibernate 5.6 support in 8.0.0. Ship both:
-
-| Path | Module | Status |
-|------|--------|--------|
-| Hibernate 5.6-jakarta | `grails-data-hibernate5` | Safe default for migration from Grails 7 |
-| Hibernate 7.2 | `grails-data-hibernate7` | Modern target; recommended for new projects |
-
-
-**Priority**: CRITICAL  
-**Effort**: Very High (binder refactoring must be applied to both versions; module consolidation required)
-
-
-
-
-### 2.6 GORM Query Safety Audit
-
-
-**8.1+ scope** (requires Groovy 5 features, deeper changes):
-- Replace GORM dynamic finders with AST-generated static methods
-- Replace `NamedCriteriaProxy.methodMissing` with generated methods
diff --git a/grails-data-hibernate7/PMD.md b/grails-data-hibernate7/PMD.md
deleted file mode 100644
index 3597e8a665..0000000000
--- a/grails-data-hibernate7/PMD.md
+++ /dev/null
@@ -1,128 +0,0 @@
-PMD Error,Fully Qualified Class,Line Number,DONE
-CloseResource,org.grails.orm.hibernate.cfg.GrailsHibernateUtil,84,YES
-CloseResource,org.grails.orm.hibernate.cfg.GrailsHibernateUtil,108,YES
-CloseResource,org.grails.orm.hibernate.cfg.GrailsHibernateUtil,113,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.GrailsHibernateUtil,120,YES
-UseProperClassLoader,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,116,YES
-UseProperClassLoader,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,137,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,190,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,195,YES
-UseProperClassLoader,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,197,YES
-UseProperClassLoader,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,249,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,254,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,275,YES
-CloseResource,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,290,YES
-CloseResource,org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,315,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ClassPropertiesBinder,72,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder,228,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder,229,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,80,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,81,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,82,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,83,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,84,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,139,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,68,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,69,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,70,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder,69,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder,85,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.DiscriminatorPropertyBinder,68,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBinder,227,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,75,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder,120,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.NumericColumnConstraintsBinder,36,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.RootBinder,78,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder,69,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder,73,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,80,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,81,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,82,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,83,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,84,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,85,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIdentityGenerator,27,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,40,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsNativeGenerator,27,YES
-EmptyCatchBlock,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsNativeGenerator,34,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsSequenceStyleGenerator,30,YES
-ConstructorCallsOverridableMethod,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsSequenceStyleGenerator,59,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsTableGenerator,30,YES
-ReturnEmptyArrayRatherThanNull,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity,50,YES
-ReturnEmptyCollectionRatherThanNull,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity,51,YES
-ReturnEmptyCollectionRatherThanNull,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,77,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,79,YES
-NullAssignment,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,82,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,82,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty,113,YES
-EmptyCatchBlock,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty,120,YES
-ReturnEmptyCollectionRatherThanNull,org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty,198,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder,94,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionWithJoinTableBinder,96,YES
-NonSerializableClass,org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPass,32,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder,73,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder,106,YES
-NonSerializableClass,org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPass,32,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPassBinder,95,YES
-NonSerializableClass,org.grails.orm.hibernate.cfg.domainbinding.secondpass.SetSecondPass,39,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator,67,YES
-EmptyCatchBlock,org.grails.orm.hibernate.cfg.domainbinding.util.CascadeBehavior,94,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.CreateKeyForProps,58,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher,49,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher,51,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,30,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,38,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,41,YES
-LoggerIsNotStaticFinal,org.grails.orm.hibernate.cfg.domainbinding.util.LogCascadeMapping,30,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,57,YES
-UseLocaleWithCaseConversions,org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,68,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,95,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,96,YES
-CompareObjectsWithEquals,org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,106,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,56,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,59,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,61,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,92,YES
-AvoidLiteralsInIfCondition,org.grails.orm.hibernate.cfg.domainbinding.util.UniqueNameGenerator,51,YES
-CloseResource,org.grails.orm.hibernate.connections.HibernateConnectionSource,53,YES
-CloseResource,org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,109,YES
-CloseResource,org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,172,YES
-AvoidCatchingThrowable,org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,237,YES
-CloseResource,org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,256,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,298,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.query.JpaCriteriaQueryCreator,131,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.query.JpaFromProvider,62,YES
-AvoidLiteralsInIfCondition,org.grails.orm.hibernate.query.JpaFromProvider,150,YES
-ProperCloneImplementation,org.grails.orm.hibernate.query.JpaFromProvider,162,YES
-CloneMethodReturnTypeMustMatchClassName,org.grails.orm.hibernate.query.JpaFromProvider,162,YES
-CloneThrowsCloneNotSupportedException,org.grails.orm.hibernate.query.JpaFromProvider,162,YES
-MissingSerialVersionUID,org.grails.orm.hibernate.query.PagedResultList,31,YES
-AvoidAccessibilityAlteration,org.grails.orm.hibernate.support.ClosureEventListener,143,YES
-AvoidAccessibilityAlteration,org.grails.orm.hibernate.support.ClosureEventListener,145,YES
-EmptyCatchBlock,org.grails.orm.hibernate.support.ClosureEventListener,146,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,188,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,215,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,232,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,312,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,315,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,341,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,343,YES
-CompareObjectsWithEquals,org.grails.orm.hibernate.support.ClosureEventListener,361,YES
-CompareObjectsWithEquals,org.grails.orm.hibernate.support.ClosureEventListener,383,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,387,YES
-CloseResource,org.grails.orm.hibernate.support.ClosureEventListener,400,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventListener,401,YES
-NonSerializableClass,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,73,YES
-NonSerializableClass,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,75,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,235,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,292,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,293,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,309,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,332,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,401,YES
-CloseResource,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,94,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,94,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,96,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,103,YES
-CloseResource,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,104,YES
-DataflowAnomalyAnalysis,org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,105,YES
diff --git a/grails-data-hibernate7/README.md b/grails-data-hibernate7/README.md
index 8a3144d848..2eafecfb69 100644
--- a/grails-data-hibernate7/README.md
+++ b/grails-data-hibernate7/README.md
@@ -1,14 +1,14 @@
-# GORM for Hibernate 6
+# GORM for Hibernate 7
 This project implements [GORM](https://gorm.grails.org) for the Hibernate 7.
 
-With the removal of Criterion API in Hibernate 6, we wanted to continue to support the DetachedCriteia in GORM as much as possible. We also wanted to encapsulate the JPA Criteria Building in one class so the following was done:
+With the removal of Criterion API in Hibernate 7, we wanted to continue to support the DetachedCriteia in GORM as much as possible. We also wanted to encapsulate the JPA Criteria Building in one class so the following was done:
 * DetachedCriteria holds almost all the state of the Query being built. It hold the target class for the query. It does not hold a session.
-* AbstractHibernateQuery has a session and holds the DetachedCriteria and is a thin wrapper for it. Calling list or singleResult will internally create the Query and execute it. 
+* HibernateQuery has a session and holds the DetachedCriteria and is a thin wrapper for it. Calling list or singleResult will internally create the Query and execute it. 
 * HibernateCriteriaBuilder is a thin wrapper around HibernateQuery. Its main function is to use closures to populate the Hibernate Query and execute it at the end of the closure.
 * Only the grails-datastore-gorm-hibernate7 module is being developed at the time.
 
 For testing the following was done:
-* Used testcontainers of postgres instead of h2 because h2 does not support all the Java Types correctly.
+* Used testcontainers for specific  tests instead of h2 to verify features not supported by h2.
 * A more opinionated and fluent HibernateGormDatastoreSpec is used for the specifications.
 
 ### Largest Gaps
diff --git a/grails-data-hibernate7/STATUS.md b/grails-data-hibernate7/STATUS.md
deleted file mode 100644
index 400d8bb359..0000000000
--- a/grails-data-hibernate7/STATUS.md
+++ /dev/null
@@ -1,112 +0,0 @@
-<!--
-SPDX-License-Identifier: Apache-2.0
-
-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.
--->
-
-# `grails-data-hibernate7` — Goals Status
-
-> Goals defined in [`UPGRADE.md`](UPGRADE.md). Last updated: 2026-02-24.
-
----
-
-## Section 0.3 — Hibernate Dual-Version Support
-
-| Goal | Status | Notes |
-|------|--------|-------|
-| `grails-data-hibernate6` removed | ✅ Done | Only `hibernate5` and `hibernate7` in `settings.gradle` |
-| Fully decomposed `domainbinding/binder/` hierarchy | ✅ Done | 20+ binders: `ClassBinder`, `ComponentBinder`, `ManyToOneBinder`, `CollectionBinder`, etc. |
-| `HibernateCriteriaBuilder` with `CriteriaMethodInvoker`/`CriteriaMethods` | ✅ Done | Refactored; direct-call specs written for JaCoCo visibility |
-| `HibernateHqlQuery`/`HqlQueryContext` split | ✅ Done | `HqlQueryContext` extracted into its own class |
-| Each binder has its own Spock spec | ✅ Done | 240 test specs, 1609 tests, 0 failures |
-| Hibernate 7 functional test examples | ✅ Done | 10 example projects (grails-hibernate, multi-datasource, multi-tenancy, data-service, etc.) |
-| Apply binder refactoring to `grails-data-hibernate5` | ❌ Not done | `grails-data-hibernate5` still uses monolithic `GrailsDomainBinder` |
-
----
-
-## Section 1.4 — Static Compilation (Target: 90%+)
-
-| Metric | Status | Notes |
-|--------|--------|-------|
-| Core module Groovy files with `@CompileStatic` | ✅ 94% (62/66) | |
-| Missing 4 files | ✅ Acceptable | All in `dbmigration/` submodule (scripts + plugin descriptor) |
-| JaCoCo branch coverage | ⚠️ 66% branches | No enforced minimum; gaps are in `transaction` and `datasource` packages (0%) and dynamic dispatch paths in `grails.orm` |
-
----
-
-## Section 2.6 — GORM Query Safety Audit
-
-| Item | Status | Notes |
-|------|--------|-------|
-| `DefaultSchemaHandler` schema name DDL injection | ✅ Fixed | `quoteName()` with JDBC identifier quoting; 9 tests |
-| `find/findAll/executeQuery/executeUpdate(CharSequence)` plain `String` guard | ✅ Fixed | `requireGString()` throws `UnsupportedOperationException`; 43 tests |
-| `findWithSql`/`findAllWithSql` renamed to `findWithNativeSql`/`findAllWithNativeSql` | ✅ Fixed | Old names `@Deprecated` and delegating |
-| `nextId()` dead code removed | ✅ Fixed | No callers; left over from Hibernate 5 |
-| Safe query patterns documented | ✅ Done | `hql.adoc`, `nativeSql.adoc`, `upgradeNotes.adoc` |
-| Compile-time GString warning (AST transform) | ✅ Superseded | Runtime exception at API boundary is stronger than a compile-time warning |
-
-Full detail: [`GORM-QUERY-SAFETY-AUDIT.md`](GORM-QUERY-SAFETY-AUDIT.md)
-
----
-
-## Section 4.1 — ExpandoMetaClass Elimination
-
-| Item | Status | Notes |
-|------|--------|-------|
-| `HibernateMappingBuilder.methodMissing` DSL replacement | ⚠️ Not started | Explicitly scoped to **8.1+** in `UPGRADE.md` — expected |
-| `HibernateGormStaticApi.propertyMissing` | ⚠️ Present | Named criteria proxy dispatch; also 8.1+ scope |
-
----
-
-## Test Coverage
-
-> Last measured: 2026-02-24 (after MultiTenantEventListenerSpec, TraitPropertyAccessStrategySpec, HqlQueryContextSpec)
-
-| Package | Instructions | Branches | Status |
-|---------|-------------|----------|--------|
-| `org.hibernate.proxy` | 100% | 100% | ✅ |
-| `grails.gorm.hibernate.mapping` | 98% | 50% | ✅ |
-| `org.grails.orm.hibernate.cfg.domainbinding.collectionType` | 97% | N/A | ✅ |
-| `org.grails.orm.hibernate.cfg.domainbinding.binder` | 95% | 85% | ✅ |
-| `org.grails.orm.hibernate.cfg.domainbinding.util` | 93% | 83% | ✅ |
-| `org.grails.orm.hibernate.compiler` | 93% | 53% | ✅ |
-| `org.grails.orm.hibernate.cfg.domainbinding.generator` | 90% | 59% | ✅ |
-| `org.grails.orm.hibernate.cfg.domainbinding.hibernate` | 88% | 74% | ✅ |
-| `org.grails.orm.hibernate.dirty` | 88% | 76% | ✅ |
-| `org.grails.orm.hibernate.query` | 87% | 77% | ✅ |
-| `org.grails.orm.hibernate.event.listener` | 84% | 59% | ✅ |
-| `grails.orm` | 80% | 69% | ✅ |
-| `org.grails.orm.hibernate.connections` | 78% | 59% | ⚠️ |
-| `org.grails.orm.hibernate.cfg.domainbinding.secondpass` | 76% | 56% | ⚠️ |
-| `org.grails.orm.hibernate.multitenancy` | 76% | 79% | ⚠️ |
-| `org.grails.orm.hibernate` | 75% | 54% | ⚠️ |
-| `org.grails.orm.hibernate.access` | 73% | 56% | ⚠️ |
-| `org.grails.orm.hibernate.cfg` | 72% | 64% | ⚠️ |
-| `org.grails.orm.hibernate.proxy` | 62% | 61% | ⚠️ |
-| `org.grails.orm.hibernate.support` | 61% | 65% | ⚠️ |
-| `org.grails.orm.hibernate.exceptions` | 11% | N/A | ℹ️ No functional code — 4 exception classes (constructors only); low coverage expected |
-| **Overall** | **81%** | **68%** | ⚠️ |
-
----
-
-## Summary
-
-| Tier | Item | Status |
-|------|------|--------|
-| 0.3 | `hibernate6` removal | ✅ Done |
-| 0.3 | Binder decomposition (`hibernate7`) | ✅ Done |
-| 0.3 | Binder refactoring applied to `hibernate5` | ❌ Not done |
-| 1.4 | Static compilation — core module | ✅ 94% |
-| 2.6 | GORM query safety audit | ✅ Done |
-| 4.1 | `methodMissing` elimination | ⚠️ 8.1+ scope |
-| — | `transaction`/`datasource` test coverage | ❌ 0% (+ `exceptions` 11%) |
diff --git a/grails-data-hibernate7/UPGRADE.md b/grails-data-hibernate7/UPGRADE.md
deleted file mode 100644
index 13a3fbf2b4..0000000000
--- a/grails-data-hibernate7/UPGRADE.md
+++ /dev/null
@@ -1,1019 +0,0 @@
-<!--
-SPDX-License-Identifier: Apache-2.0
-
-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.
--->
-
-# Grails 8: Prioritized Modernization Roadmap
-
-**Target**: Q2 2026 milestone releases
-**Stack**: Spring Boot 4.0.x / Spring Framework 7.0.x / Groovy 5 / Hibernate 7.x/5.6.x / Java 17+ (25 recommended) / Gradle 9
-
----
-
-## Table of Contents
-
-- [Current State of Grails 8 Work](#current-state-of-grails-8-work)
-- [Tier 0 - Gate Blockers](#tier-0---gate-blockers-nothing-ships-without-these)
-- [Tier 1 - Performance and Startup](#tier-1---performance-and-startup)
-- [Tier 2 - Security Hardening](#tier-2---security-hardening)
-- [Tier 3 - Modern Runtime Features](#tier-3---modern-runtime-features)
-- [Tier 4 - Compile-Time Shift](#tier-4---compile-time-shift)
-- [Tier 5 - Developer Experience](#tier-5---developer-experience)
-- [Tier 6 - Ecosystem and Future-Proofing](#tier-6---ecosystem-and-future-proofing)
-- [What NOT to Do in Grails 8](#what-not-to-do-in-grails-8)
-- [Appendix: Competitive Landscape](#appendix-competitive-landscape)
-
----
-
-## Current State of Grails 8 Work
-
-### Active Branches
-
-| Branch | Focus | Scale |
-|--------|-------|-------|
-| `8.0.x` | Main Grails 8 integration branch | 145 files changed from 7.0.x, URL mapping fixes, constraint expansion, multi-datasource fixes |
-| `8.0.x-hibernate7` | Hibernate 7 + GrailsDomainBinder refactor | **2,821 files changed, 145k+ insertions** - massive refactor decomposing monolithic binder into proper binder hierarchy. Contains three hibernate modules (`hibernate5`, `hibernate6`, `hibernate7`); **hibernate6 will be removed** (see Section 0.3) |
-
-### Open PRs Targeting Grails 8 (`relates-to:v8`)
-
-| PR | Title | Status | Impact |
-|----|-------|--------|--------|
-| [#15354](https://github.com/apache/grails-core/pull/15354) | **Spring Boot 4.0.1 + Spring Framework 7.0.2** | CI passing, tests green | Foundation - all other v8 work depends on this |
-| [#15183](https://github.com/apache/grails-core/pull/15183) | **Groovy 5 Compatibility** | Blocker label, 23 commits, 31 files | Foundation - required for static compilation improvements and modern Groovy features |
-| [#15365](https://github.com/apache/grails-core/pull/15365) | **Gradle 9.3.1 + Micronaut 4** | CI passing | Build infrastructure - fixes deprecated APIs, enables Gradle 10 readiness |
-| [#15367](https://github.com/apache/grails-core/pull/15367) | **JLine 3.30.6 + Jansi 2.4.2** | CI passing, 100+ new tests | CLI modernization - JLine 2 is EOL |
-
-### Open Issues Targeting Grails 8
-
-| Issue | Title | Severity |
-|-------|-------|----------|
-| [#13757](https://github.com/apache/grails-core/issues/13757) | Grails 8 Feature Set tracking issue | Tracking |
-| [#15374](https://github.com/apache/grails-core/issues/15374) | **Indy 4x performance regression** from metaclass invalidation | Critical |
-| [#14956](https://github.com/apache/grails-core/issues/14956) | Hibernate 7.x.x support | High |
-| [#14738](https://github.com/apache/grails-core/issues/14738) | Gradle 9 support | High |
-| [#14736](https://github.com/apache/grails-core/issues/14736) | Groovy 5 support | Blocker |
-| [#14915](https://github.com/apache/grails-core/issues/14915) | Spring 7 - XML configuration no longer supported (Bean Builder rework) | Blocker |
-| [#15377](https://github.com/apache/grails-core/issues/15377) | hibernate5-dbmigration bootWar NPE in WAR deployment | High |
-
----
-
-## Tier 0 - Gate Blockers (Nothing Ships Without These)
-
-These are the highest-priority items for Grails 8.
-
-### 0.1 Spring Boot 4 + Spring Framework 7 Compatibility
-
-**PR**: [#15354](https://github.com/apache/grails-core/pull/15354) (ready for merge)
-**Status**: CI green, all test suites passing. Uses Groovy 4.0.x + Hibernate 5.6-jakarta as an interim.
-
-**Remaining work after merge**:
-- Update `grails-spring-security` plugin for `ReflectionUtils.getApplication()` removal
-- Fix SiteMesh3 decorator integration for Spring Framework 7
-- Fix JSP rendering under Spring Boot 4 servlet configuration
-- Address JSON Views error handling timeout
-- Rework Bean Builder - Spring 7 drops XML configuration support ([#14915](https://github.com/apache/grails-core/issues/14915)); the current BeanBuilder is backed by XML; needs programmatic bean registration
-
-**Breaking changes apps must handle**:
-- Package relocations (6 autoconfigure classes moved)
-- MongoDB property renames (`spring.data.mongodb.*` to `spring.mongodb.*`)
-- `DefaultTransactionStatus` constructor now requires 8 parameters
-- `HandlerAdapter.getLastModified()` removed
-- Theme support removed from DispatcherServlet (vendored into Grails for GSP)
-
-#### PR #15354 Changes
-
-| Category | Change | Files |
-|----------|--------|-------|
-| **Vendored Spring Framework code** | Spring 7 removed theme support from `DispatcherServlet`. GSP requires it. Vendored `ThemeResolver`, `SessionThemeResolver`, `ResourceBundleThemeSource`, `UiApplicationContextUtils`, `SimpleTheme` etc. into `grails-spring` | 12 new files in `grails-spring/src/main/java/org/springframework/` |
-| **Vendored Spring ORM code** | Spring 7 removed Hibernate 5 ORM integration classes. Vendored `HibernateTemplate`, `HibernateTransactionManager`, `HibernateOperations`, `LocalSessionFactoryBean`, `LocalSessionFactoryBuilder`, `SessionFactoryUtils`, `SessionHolder`, etc. into `grails-data-hibernate5` | 16 new files in `grails-data-hibernate5/core/src/main/java/.../hibernate5/` |
-| **Package relocations** | Updated imports for 6 autoconfigure classes that moved in Spring Boot 4 | `ApplicationClassInjector`, `GrailsApplicationCompilerAutoConfiguration`, `ControllersAutoConfiguration`, `GrailsFilters`, `MongoDbGormAutoConfiguration` |
-| **MongoDB property renames** | `spring.data.mongodb.*` to `spring.mongodb.*` | `application.yml`, `StartMongoGrailsIntegrationExtension`, MongoDB test specs |
-| **Removed API replacements** | `SecurityProperties.DEFAULT_FILTER_ORDER` replaced with hardcoded `-100`; `AnnotationConfigServletWebApplicationContext` replaced with `GenericWebApplicationContext`; `MappedInterceptor.matches(String,PathMatcher)` replaced with `matches(HttpServletRequest)` | `GrailsFilters`, `GrailsApplicationBuilder`, `UrlMappingsHandlerMapping` |
-| **Constructor signature changes** | `DefaultTransactionStatus` now requires 8 params (added `transactionName` and `nested`) | `TransactionalTransformSpec` |
-| **Deprecated method removal** | `HandlerAdapter.getLastModified()` removed from interface | `UrlMappingsInfoHandlerAdapter` |
-| **Test support updates** | `MockApplicationContext` added `getBeanProvider(ParameterizedTypeReference)`; `AbstractGrailsTagTests` added static constants for removed theme attributes | `MockApplicationContext.java`, `AbstractGrailsTagTests` |
-
-#### PR #15354 Workarounds
-
-| Workaround | Reason | Impact |
-|------------|--------|--------|
-| Vendored Spring theme classes into `grails-spring` | Spring 7 removed theme support; GSP layouts depend on `ThemeResolver` | Maintenance burden - vendored code won't get Spring updates. Should migrate GSP away from theme API in 8.1+ |
-| Vendored Spring Hibernate 5 ORM classes into `grails-data-hibernate5` | Spring 7 removed Hibernate 5 integration | Required only for the Hibernate 5.6-jakarta path. Goes away when apps migrate to Hibernate 7.2 |
-| Hardcoded `DEFAULT_FILTER_ORDER = -100` in `GrailsFilters` | `SecurityProperties.DEFAULT_FILTER_ORDER` removed | Fragile if Spring Security changes the default. Should use Spring Security's constant when security plugin is updated |
-
-#### PR #15354 Disabled Tests (External Plugin Incompatibilities)
-
-| Test | Plugin/Library | Root Cause | Action Needed |
-|------|---------------|------------|---------------|
-| `app3/LoadAfterSpec` | Spring Security 7.0.1-SNAPSHOT | `ReflectionUtils.getApplication()` removed in Spring Boot 4 | Update grails-spring-security plugin |
-| `exploded/LoadAfterSpec` | Spring Security | Same as above | Same |
-| `plugins/exploded/PluginDependencySpec` | Spring Security | Same as above | Same |
-| `mongodb/test-data-service/TestServiceSpec` | Spring Security | Same as above | Same |
-| `mongodb/test-data-service/StudentServiceSpec` | Spring Security | Same as above | Same |
-| `gsp-sitemesh3/GrailsLayoutSpec` | SiteMesh3 | Decorator/layout not compatible with Spring Framework 7 | Update SiteMesh3 integration |
-| `gsp-sitemesh3/EndToEndSpec` | SiteMesh3 | Same as above | Same |
-| `gsp-layout/GrailsLayoutSpec` (JSP test only) | JSP support | JSP pages not rendering under Spring Boot 4 servlet config | Fix servlet JSP config or document as unsupported |
-| `issue-views-182/CustomErrorSpec` | JSON Views | Error handling response times out | Debug timeout root cause |
-| `RenderMethodTests.testRenderFile` (`@PendingFeature`) | MockHttpServletResponse | Behavior changed in Spring Framework 7 | Update test expectations |
-
-#### PR #15354 Open Decisions
-
-| Decision | Context | Options |
-|----------|---------|---------|
-| **GSP theme support long-term** | Vendored Spring theme classes are a maintenance liability | (a) Keep vendored code for 8.x lifecycle, (b) Migrate GSP to a Grails-native theming mechanism, (c) Deprecate theme support entirely |
-| **SiteMesh3** | SiteMesh3 is incompatible with Spring 7 | (a) Request update to SiteMesh3, (b) Replace with Grails-native layout mechanism |
-| **JSP support** | JSP rendering broken under Spring Boot 4 | (a) Fix and continue supporting, (b) Deprecate JSP in Grails 8 (GSP is the primary view technology) |
-
-**Priority**: **CRITICAL** - Foundation for everything else.
-**Effort**: Medium (PR exists, needs merge + follow-up fixes)
-
----
-
-### 0.2 Groovy 5 Compatibility
-
-**PR**: [#15183](https://github.com/apache/grails-core/pull/15183) (blocker label, by matrei)
-**Status**: 23 commits, 31 files changed. Supersedes earlier #14737.
-
-**Why this is a gate blocker**:
-- Groovy 5 drops legacy APIs that Grails 7 relies on
-- Groovy 5 brings improved static compilation that enables Tier 4 (compile-time shift)
-- Groovy 5 introduces records, sealed classes, and GINQ improvements
-- JLine 2 dependency in Groovy 4.x groovysh is removed in Groovy 5 (unblocks [#15367](https://github.com/apache/grails-core/pull/15367) cleanup)
-
-#### PR #15183 Changes
-
-| Category | Change | Files |
-|----------|--------|-------|
-| **Groovy version bump** | `dependencies.gradle` updated to Groovy 5.0.5-SNAPSHOT | `dependencies.gradle` |
-| **Static trait method fix** | `Validateable.getConstraintsMap()` - static trait method dispatch changed | `Validateable.groovy` |
-| **Closure type workarounds** | `@CompileDynamic` added where Groovy 5 rejects closure union types | `BoundPromise.groovy`, `JspTagImpl.groovy` |
-| **VariableScopeVisitor NPE guards** | Groovy 5 changed AST visitor behavior; added try-catch wrappers | `GrailsASTUtils.java`, `AstUtils.groovy`, `LoggingTransformer.java` |
-| **ConfigObject recursion fix** | `NavigableMap.merge()` hits infinite recursion with Groovy 5 ConfigObject | `NavigableMap.groovy` |
-| **Trait static method extraction** | Moved static SQL methods out of `HibernateEntity` trait (joint compilation issue) | `HibernateEntity.groovy`, `HibernateMappingContext.java` |
-| **ClosureExpression VariableScope** | Groovy 5 requires non-null VariableScope on programmatic closures | `AbstractMethodDecoratingTransformation.groovy`, `ResourceTransform.groovy` |
-| **InnerClassNode handling** | `GormEntityTransformation` no longer checks `InnerClassNode` | `GormEntityTransformation.groovy` |
-| **@ApiDelegate default** | Added `default Object.class` for Groovy 5 annotation processing | `ApiDelegate.java`, `ApiDelegateTransformation.java` |
-| **@Builder retention change** | `ConfigurationBuilder` handles `@Builder` being SOURCE-only in Groovy 5 | `ConfigurationBuilder.groovy` |
-| **i18n fallback** | `AbstractConstraint` falls back to direct `ResourceBundle` lookup | `AbstractConstraint.java` |
-| **Spock/test compatibility** | `@IgnoreIf` for final method mocking; removed `spock-core transitive=false` | 30+ `build.gradle` files, multiple test specs |
-| **MongoDB codec fixes** | Updated for Groovy 5 type changes | `BsonPersistentEntityCodec`, `PersistentEntityCodec`, `MongoCodecSession` |
-
-#### PR #15183 Workarounds
-
-| Workaround | Reason | Permanent Fix Path |
-|------------|--------|--------------------|
-| `@CompileDynamic` on `BoundPromise.then()` | Groovy 5 rejects `Closure<T>` union types under static compilation | Redesign method signature or wait for upstream Groovy fix |
-| `@CompileDynamic` on `JspTagImpl.applyAttributes()` | Same closure union type issue with `instanceof` checks | Same |
-| `metaClass.invokeStaticMethod` in `Validateable` | Static trait method resolves to trait's version, not implementor's override | File upstream Groovy bug or move `getConstraintsMap()` out of trait |
-| Try-catch around `VariableScopeVisitor` calls | Groovy 5 throws NPE in certain AST transformation scenarios | Report upstream - Groovy 5 should handle these states gracefully |
-| `NavigableMap` ConfigObject conversion | ConfigObject infinite recursion in Groovy 5 | Decide NavigableMap future ([#14005](https://github.com/apache/grails-core/issues/14005)) |
-| `@IgnoreIf` on tests mocking final methods | Groovy 5/ByteBuddy cannot mock finals | Rewrite tests to avoid mocking finals |
-
-#### Groovy 5 Compatibility Fixes, Workarounds, and Open Decisions (Detailed)
-
-Based on commit [`9574fe8`](https://github.com/apache/grails-core/commit/9574fe8f7f6a1d230b895c8b1df76fd5b6860df9) (66 files changed across 30+ modules), the following is a categorized inventory of what Groovy 5 breaks and the current fix status:
-
-**Workarounds (temporary - need proper fix or upstream Groovy resolution):**
-
-| Area | File(s) | Issue | Current Workaround | Decision Needed |
-|------|---------|-------|--------------------|-----------------|
-| Closure union types | `BoundPromise.groovy`, `JspTagImpl.groovy` | Groovy 5 static compiler rejects closure return types that vary (`Closure<T>` union types, `instanceof` checks in closures) | Added `@CompileDynamic` to affected methods | Upstream Groovy bug? Or redesign method signatures to avoid union types so `@CompileStatic` can be restored |
-| Static trait method resolution | `Validateable.groovy` | `this.defaultNullable()` in a static trait method resolves to the trait's version instead of the implementing class's override in Groovy 5 | Replaced with `metaClass.invokeStaticMethod` (dynamic dispatch) | This is a behavioral regression in Groovy 5. File upstream bug? Or redesign Validateable to not rely on static method overrides in traits |
-| VariableScopeVisitor NPE | `GrailsASTUtils.java`, `AstUtils.groovy` | Groovy 5 changed how `VariableScopeVisitor` handles certain AST states; throws NPE during transformations | Wrapped calls in try-catch | Report upstream. These are AST transform edge cases that Groovy 5 should handle gracefully |
-| LogASTTransformation NPE | `LoggingTransformer.java` | `LogASTTransformation.visit()` throws NPE in `VariableScopeVisitor` during Groovy 5 | Wrapped in try-catch | Same root cause as VariableScopeVisitor NPE above - single upstream fix would resolve both |
-| ConfigObject infinite recursion | `NavigableMap.groovy` | Merging a `ConfigObject` into `NavigableMap` causes infinite recursion in Groovy 5 (ConfigObject behavior changed) | Added explicit `ConfigObject` conversion method before merge | Decide: is `NavigableMap` still needed? ([#14005](https://github.com/apache/grails-core/issues/14005) proposes optimizing/replacing it). If kept, needs proper ConfigObject handling, not a workaround |
-
-**Proper Fixes (completed - no further action needed):**
-
-| Area | File(s) | Issue | Fix Applied |
-|------|---------|-------|-------------|
-| `@Builder` SOURCE retention | `ConfigurationBuilder.groovy` | Groovy 5 changed `@Builder` annotation retention; `@Builder(builderStrategy=SimpleStrategy)` is now SOURCE-only | Added `ConverterNotFoundException` handling and guarded builder-prefix method detection to work without runtime annotation |
-| Static methods in traits (joint compilation) | `HibernateEntity.groovy`, `HibernateMappingContext.java` | See detailed analysis below | See detailed analysis below |
-| ClosureExpression VariableScope | `AbstractMethodDecoratingTransformation.groovy`, `ResourceTransform.groovy` | Groovy 5 requires `ClosureExpression` to have a non-null `VariableScope` for bytecode generation | Set explicit `VariableScope` on all programmatically-created closures in AST transforms |
-| InnerClassNode handling | `GormEntityTransformation.groovy` | Groovy 5 changed `InnerClassNode` classification | Removed `InnerClassNode` import; updated `instanceof` check to use `classNode.isEnum()` only |
-| `@ApiDelegate` default value | `ApiDelegate.java`, `ApiDelegateTransformation.java` | Groovy 5 requires annotation attributes with no default to be explicitly provided | Added `default Object.class` to `@ApiDelegate.value()`; transformation checks for default before using |
-| i18n message fallback | `AbstractConstraint.java` | `ConstrainedProperty.DEFAULT_MESSAGES` static map not populated in Groovy 5 context | Added `getDefaultMessageFromBundle()` method that falls back to direct `ResourceBundle` lookup from `MESSAGE_BUNDLE` |
-| Spock test mocking | Multiple test specs | Groovy 5 / ByteBuddy cannot mock final methods (Groovy 5 makes more methods final) | Added `@IgnoreIf` with Groovy 5 version detection; standardized `isGroovy5()` helper across specs |
-| spock-core transitive deps | 30+ `build.gradle` files | Spock 2.3 with Groovy 5 requires different transitive dependency handling | Removed `transitive=false` from spock-core dependencies; let Gradle resolve Groovy 5-compatible transitives |
-
-**Static Methods in Traits - Joint Compilation Problem (detailed analysis from [PR #15183 comment](https://github.com/apache/grails-core/pull/15183#issuecomment-3854397217)):**
-
-The issue is **NOT** that Groovy 5 prohibits static methods in traits. `GormEntity` has 87+ static methods and works fine. The issue is **joint compilation with Java files that directly import the trait**.
-
-| Trait | Module | Static Methods | Java Files Import It? | Result in Groovy 5 |
-|-------|--------|----------------|----------------------|-------------------|
-| `GormEntity` | grails-datamapping-core | 87 | **No** | Works |
-| `HibernateEntity` | grails-data-hibernate5-core | 5 | **Yes** (`HibernateMappingContext.java`) | **Fails** |
-| `MongoEntity` | grails-data-mongodb | 18 | No | Works |
-| `Neo4jEntity` | grails-data-neo4j | 10 | No | Works |
-
-When a Java file in the same module imports a Groovy trait with static methods that return generic type parameters (`D`), the Groovy stub generator creates invalid Java code:
-
-```java
-// Generated stub (INVALID Java)
-@groovy.transform.Generated()
-static java.util.List<D> findAllWithSql(java.lang.CharSequence sql);
-//                    ^ ERROR: non-static type variable D cannot be
-//                      referenced from static context
-```
-
-In Java, you cannot use a class-level type parameter (`D`) in a static method signature. The Groovy trait works because Groovy handles this differently at runtime, but the stub generator doesn't account for this.
-
-**Potential solutions** (decision needed):
-
-| Approach | Description | Trade-off |
-|----------|-------------|-----------|
-| **Remove Java import via reflection** | Modify `HibernateMappingContext.java` to load `HibernateEntity` via `Class.forName()` instead of direct import, avoiding stub generation ([commit `425d2da`](https://github.com/apache/grails-core/commit/425d2da3b633fa471ad64dbb21a92c1327a5268b)) | Loses compile-time type safety in `HibernateMappingContext`; adds reflection call |
-| **Move class to another module** | Move `HibernateMappingContext.java` to a module that doesn't jointly compile with `HibernateEntity.groovy` | Module restructuring; may create circular dependency |
-| **Convert Java class to Groovy** | Rewrite `HibernateMappingContext.java` as `HibernateMappingContext.groovy` so it goes through Groovy compilation, not Java stub compilation | Groovy compilation is slower; may affect `@CompileStatic` coverage |
-| **Move static methods to companion** | Extract the 5 static SQL methods to a `HibernateEntityStaticApi` helper class, keep the trait pure instance methods | Changes API surface; existing code calling `HibernateEntity.findAllWithSql()` must change |
-| **Fix Groovy stub generator** | File upstream Groovy bug to generate proper `<D>` type parameter on static stubs | Depends on Groovy team timeline; not in our control |
-
-**Open Decisions (require architectural discussion):**
-
-| Decision | Context | Options |
-|----------|---------|---------|
-| **`@CompileDynamic` workarounds - accept or fix?** | Two methods (`BoundPromise.then()`, `JspTagImpl.applyAttributes()`) dropped from `@CompileStatic` to `@CompileDynamic`. This is a performance regression on hot paths (Indy call site caching defeated). | (a) Accept for 8.0.0, fix in 8.1 if Groovy 5 adjusts for Grails, (b) Redesign method signatures now to avoid union types, (c) File Groovy JIRA and wait for upstream fix |
-| **Validateable static trait dispatch** | The `metaClass.invokeStaticMethod` workaround defeats static compilation for constraint evaluation. Every `validate()` call goes through dynamic dispatch. | (a) Accept perf hit, (b) Move `getConstraintsMap()` out of the trait into a registry/helper class, (c) File Groovy 5 bug for static trait method resolution |
-| **NavigableMap future** | NavigableMap is deprecated ([#14005](https://github.com/apache/grails-core/issues/14005)). The Groovy 5 ConfigObject fix is a band-aid. | (a) Remove NavigableMap entirely in 8.0 (breaking), (b) Keep with workaround, remove in 8.1, (c) Replace with flattened `PropertySource`-based config |
-| **HibernateEntity static trait methods** | 5 static methods on `HibernateEntity` fail joint compilation with `HibernateMappingContext.java` due to Groovy 5 stub generator producing invalid generic type parameters in static context. See detailed analysis above. | (a) Reflection-based import avoidance (proven in `425d2da`), (b) Move Java class to different module, (c) Convert Java to Groovy, (d) Move static methods to companion class, (e) Fix Groovy stub generator upstream |
-| **Test coverage gaps from `@IgnoreIf`** | Several tests are skipped on Groovy 5 due to mocking limitations. These test features (mocking final methods, static method mocking) that Groovy 5 restricts. | (a) Rewrite tests to not mock finals (preferred), (b) Use PowerMock/Mockito inline for final mocking, (c) Accept coverage gap |
-| **Groovy 5 SNAPSHOT vs release** | Current work targets Groovy 5.0.5-SNAPSHOT. API surface may still shift before GA. | Track Groovy 5 release candidates closely. Avoid relying on any behavior that is explicitly marked as "subject to change" in Groovy 5 release notes. |
-
-**Priority**: **CRITICAL** - Blocks modern language features and Indy fixes.
-**Effort**: High (active work, 66 files touched, multiple open architectural decisions)
-
----
-
-### 0.3 Hibernate Dual-Version Support (5.6-jakarta + 7.2)
-
-**Branch**: `8.0.x-hibernate7` (2,821 files changed, 145k+ insertions)
-**Issue**: [#14956](https://github.com/apache/grails-core/issues/14956)
-
-Grails 8 can ship with a **choice** between Hibernate 5.6-jakarta (legacy, proven) and Hibernate 7.2 (modern, Spring Boot 4 native). The Spring Boot 4 PR ([#15354](https://github.com/apache/grails-core/pull/15354)) already passes CI with Hibernate 5.6-jakarta, proving the 5.6 path works today.
-
-#### Module Consolidation: Remove `grails-data-hibernate6`
-
-The `8.0.x-hibernate7` branch currently contains three hibernate modules: `grails-data-hibernate5` (588 files), `grails-data-hibernate6` (588 files), and `grails-data-hibernate7` (708 files). **`grails-data-hibernate6` should be removed.** It is a development stepping stone that served its purpose during the binder refactoring but has no place in the final release:
-
-| Module | Hibernate | Binder Architecture | Gaps | Ship in Grails 8? |
-|--------|-----------|---------------------|------|--------------------|
-| `grails-data-hibernate5` | 5.6-jakarta | Monolithic `GrailsDomainBinder` (to be refactored) | None (production) | **Yes** - legacy path |
-| `grails-data-hibernate6` | 6.x | Partial decomposition - still has `AbstractGrailsDomainBinder` + flat `domainbinding/` | Multitenancy, Proxy support | **No - remove** |
-| `grails-data-hibernate7` | 7.2 | Fully decomposed `domainbinding/binder/` hierarchy + generators + entity hierarchy | None | **Yes** - modern path |
-
-**Why hibernate6 is redundant:**
-- Hibernate 6.x is not Spring Boot 4's target (that's 7.2) and not the legacy path (that's 5.6-jakarta)
-- hibernate7 supersedes all hibernate6 work - the 56 files unique to hibernate6 are the old binder pattern that hibernate7 replaced with 176 new files in the decomposed hierarchy
-- hibernate6 still has known gaps (multitenancy, proxy support) that hibernate7 resolved
-- Maintaining 3 modules instead of 2 triples the surface area for Hibernate API changes
-
-**Removal plan:**
-1. Delete `grails-data-hibernate6/` directory and all `grails-data-hibernate6-*` entries from `settings.gradle`
-2. Port any valuable `grails-test-examples/hibernate6/` functional tests to `hibernate7/` equivalents, then delete the hibernate6 test examples
-3. Verify no other modules reference `grails-data-hibernate6` in their build files
-
-#### Binder Refactoring (Apply to Both Versions)
-
-The massive refactoring on `8.0.x-hibernate7` (in the `grails-data-hibernate7` module) decomposes the monolithic `GrailsDomainBinder` into a proper hierarchy:
-- `RootBinder`, `SubClassBinder`, `SubclassMappingBinder`, `DiscriminatorPropertyBinder`
-- `ComponentBinder`, `CollectionSecondPassBinder`, `DependentKeyValueBinder`
-- `UnidirectionalOneToManyBinder`, `SimpleValueColumnBinder`, `PrimaryKeyValueCreator`
-- `HibernateCriteriaBuilder` refactored with `CriteriaMethodInvoker` and `CriteriaMethods` enum
-- `GrailsHibernatePersistentEntity` and `GrailsHibernatePersistentProperty` hierarchy enriched
-- Each binder now has its own Spock spec (testable in isolation)
-
-**This refactoring should be applied to the Hibernate 5.6 codebase as well.** The binder decomposition improves maintainability, testability, and code clarity regardless of the Hibernate version underneath. Having the 5.6 variant use a monolithic `GrailsDomainBinder` while the 7.2 variant has proper binder separation would make long-term maintenance significantly harder.
-
-#### Version Selection Mechanism
-
-Use **Maven classifier** and **Gradle `requireCapability`** so apps choose their Hibernate version at dependency resolution time:
-
-```groovy
-// Gradle - user's build.gradle
-dependencies {
-    // Option A: Hibernate 5.6-jakarta (legacy, default for migration)
-    implementation 'org.apache.grails:grails-data-hibernate:8.0.0:hibernate56'
-
-    // Option B: Hibernate 7.2 (modern, recommended for new projects)
-    implementation 'org.apache.grails:grails-data-hibernate:8.0.0:hibernate72'
-}
-```
-
-Or via Gradle's feature variants and `requireCapability`:
-
-```groovy
-dependencies {
-    implementation('org.apache.grails:grails-data-hibernate:8.0.0') {
-        requireCapability 'org.apache.grails:grails-data-hibernate-7.2'
-    }
-}
-```
-
-This ensures:
-- No classpath conflicts (only one Hibernate version on classpath)
-- BOM/platform support for transitive Hibernate version alignment
-- Clear migration path: start with 5.6, switch to 7.2 when ready
-- Grails Forge can offer the choice at project creation time
-
-#### Liquibase / Database Migration Plugin Concerns
-
-**Hibernate 5.6 path**: No license issue. The Database Migration plugin pins to Liquibase 4.27.0 and `liquibase-hibernate5`, both Apache 2.0 licensed. This continues to work exactly as it does in Grails 7.
-
-**Hibernate 7.2 path**: PR [liquibase/liquibase-hibernate#844](https://github.com/liquibase/liquibase-hibernate/pull/844) adds Hibernate 7 support to `liquibase-hibernate`, but it targets Liquibase 5.x. Liquibase core v5.0.0 was the first release under the new **FSL-1.1-ALv2** license (Functional Source License, Version 1.1, Apache License v2 Future License). All Liquibase core versions prior to 5.0.0 remain Apache 2.0. Under FSL-1.1-ALv2, each release reverts to Apache 2.0 two years aft [...]
-
-**ASF policy allows this as an optional dependency.** Per the [ASF third-party license policy](https://www.apache.org/legal/resolved.html): *"You may rely on them when they support an optional feature. Apache projects can rely on components under prohibited licenses if the component is only needed for optional features. When doing so, a project shall provide the user with instructions on how to obtain and install the non-included work."* The Database Migration plugin with Liquibase 5.x i [...]
-
-
-#### Why Hibernate 7 Matters
-
-- Jakarta Persistence 3.2 compliance (Jakarta EE 11)
-- Spring Boot 4 ships with Hibernate 7.2
-- Hibernate 7 drops many deprecated 5.x APIs that GORM wraps
-- Better SQL generation, stateless session improvements, annotation processor support
-
-**Priority**: **CRITICAL** - Both paths must work. 5.6-jakarta is the safe default; 7.2 is the modern target.
-**Effort**: Very High (binder refactoring underway; must apply to both versions)
-
----
-
-### 0.4 Gradle 9 Support
-
-**PR**: [#15365](https://github.com/apache/grails-core/pull/15365) (CI passing)
-**Issue**: [#14738](https://github.com/apache/grails-core/issues/14738)
-
-**What it does**:
-- Gradle 8.14.4 to 9.3.1 across all modules
-- Fixes all deprecated Gradle APIs (`convention` to `extensions`, `ConfigureUtil` to `ClosureBackedAction`, `Task.project` at execution time)
-- Upgrades Develocity plugin from 4.1.1 to 4.3.2
-- Upgrades grails-forge from Micronaut 3.10.4 to 4.10.7 (including javax to jakarta migration)
-
-**Why it's a gate blocker**:
-- Gradle 8 will eventually hit EOL; Grails 8 users need Gradle 9 support
-- Gradle 9 enforces stricter task isolation (fixes prepare for Gradle 10)
-- Micronaut 4 upgrade in grails-forge is required for modern forge features
-
-#### PR #15365 Changes
-
-| Category | Change | Files |
-|----------|--------|-------|
-| **Gradle wrapper** | 8.14.4 to 9.3.1 across all projects (root, build-logic, grails-gradle, grails-forge) | `gradle-wrapper.properties` (4), `gradlew`/`gradlew.bat` (4), `.sdkmanrc` |
-| **`convention` to `extensions`** | Replace removed `convention` API | `SbomPlugin`, `RockerPlugin`, `RockerSourceSetProperty` |
-| **`ConfigureUtil` to `ClosureBackedAction`** | Replace removed Gradle API | Gradle plugin sources |
-| **`JavaPluginConvention` to `JavaPluginExtension`** | Replace removed convention type | Build plugins |
-| **`outputFile` to `destinationFile`** | Replace deprecated `WriteProperties` API | Build plugins |
-| **`Task.project` at execution time** | Capture project properties at configuration time (required for Gradle 10) | `SbomPlugin` (projectName, projectPath, buildDate), `PublishPlugin` (PublishingExtension), `GrailsGradlePlugin` (buildDir, antBuilder), `GrailsProfileGradlePlugin` (replaced `project.sync` with `Sync` task) |
-| **Develocity plugin** | 4.1.1 to 4.3.2; `common-custom-user-data-gradle-plugin` 2.3 to 2.4.0 | `settings.gradle` files |
-| **Develocity migration** | `grails-data-neo4j` and `grails-data-graphql` from deprecated `gradle-enterprise` to `develocity` | `settings.gradle` for both subprojects |
-| **JUnit Platform launcher** | Added dependency required by Gradle 9 for test execution | `test-config.gradle`, `functional-test-config.gradle` |
-| **Micronaut 4 (grails-forge)** | 3.10.4 to 4.10.7; Groovy 3.x to 4.0.30; Spock 2.1 to 2.3 | Forge `gradle.properties`, all forge `build.gradle` files |
-| **javax to jakarta (grails-forge)** | `javax.validation.*` to `jakarta.validation.*`; `javax.transaction.*` to `jakarta.transaction.*` | Forge controllers, services |
-| **Forge dependency coordinates** | `org.codehaus.groovy` to `org.apache.groovy`; `io.micronaut:micronaut-bom` to `io.micronaut.platform:micronaut-platform` | Forge build files |
-| **ByteBuddy for Spock** | Added for Spock mocking on Java 17+ (CGLIB doesn't support Java 17 class files) | Test dependencies |
-| **`--add-opens` JVM arg** | `java.base/java.lang=ALL-UNNAMED` for test execution on Java 17+ | Test config |
-| **Coherence BOM** | Updated license mapping for version 25.03.2 | `SbomPlugin` |
-
-#### PR #15365 Workarounds
-
-None - all changes in this PR are proper fixes, not workarounds.
-
-#### PR #15365 Known Remaining Deprecations
-
-| Warning | Source | Resolution |
-|---------|--------|------------|
-| `StartParameter.isConfigurationCacheRequested` | `org.asciidoctor.jvm.convert` plugin 4.0.5 | Fix in asciidoctor-gradle-plugin 5.0.0+ (currently alpha). Tracked: [asciidoctor#756](https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/756) |
-
-#### PR #15365 Open Decisions
-
-| Decision | Context | Options |
-|----------|---------|---------|
-| **Asciidoctor plugin upgrade** | 4.0.5 has Gradle 10 deprecation warning; 5.0.0 is alpha | (a) Stay on 4.0.5 until 5.0.0 GA, (b) Accept deprecation warning |
-| **Coherence BOM license** | Updated mapping for 25.03.2 | Verify license compatibility with ASF policy |
-
-**Priority**: **CRITICAL** - Build tooling must be current.
-**Effort**: Low (PR exists and is passing)
-
----
-
-### 0.5 Bean Builder Rework for Spring 7
-
-**Issue**: [#14915](https://github.com/apache/grails-core/issues/14915)
-
-Spring Framework 7 no longer supports XML-driven MVC configuration. Grails' `BeanBuilder` is ultimately backed by XML bean definitions. Spring 7 is adding programmatic bean registration APIs as a replacement.
-
-> **Note**: The Spring Boot 4 PR ([#15354](https://github.com/apache/grails-core/pull/15354)) is somehow passing CI with the current BeanBuilder implementation. This needs investigation - it may be that Spring 7 still supports the programmatic `GenericBeanDefinition` path that BeanBuilder actually uses (as opposed to XML file parsing), or that the deprecated codepath hasn't been fully removed yet. Either way, the rework should still be planned to avoid relying on potentially removed internals.
-
-**Required action**: Rewrite `BeanBuilder` to use Spring's new programmatic `BeanRegistry` API instead of XML-backed `GenericBeanDefinition`. This is architectural - it touches how every Grails plugin registers beans via `doWithSpring`.
-
-**Priority**: **CRITICAL** - Without this, plugin bean registration breaks on Spring 7.
-**Effort**: High (architectural change, touches every plugin)
-
----
-
-## Tier 1 - Performance and Startup
-
-### 1.1 Fix Invoke Dynamic (Indy) 4x Performance Regression
-
-**Issue**: [#15374](https://github.com/apache/grails-core/issues/15374)
-**Severity**: HIGH
-
-**Root cause**: Grails frequently modifies metaclasses during request processing (GORM operations, codec registration, taglib dispatch). Each metaclass modification invalidates ALL `CacheableCallSite` targets across the entire application, forcing JIT recompilation. With Indy enabled in Groovy 4, this causes a 4x regression vs Grails 6.
-
-**Attack plan (from issue analysis)**:
-
-1. **Batch metaclass modifications at startup** - All `ExpandoMetaClass` changes should complete before the first request. No metaclass modifications during request processing.
-2. **Pre-register all GORM dynamic finders at startup** - Instead of `methodMissing` adding metaclass methods lazily on first call, register all `findBy*`, `countBy*`, `listOrderBy*` methods for all persistent properties during `GormEnhancer.enhanceAll()`.
-3. **Replace runtime metaclass codec registration** - `CodecMetaClassSupport.configureCodecMethods()` adds `encodeAsHTML()` etc. via ExpandoMetaClass. Replace with Groovy extension modules (resolved at compile time with `@CompileStatic`).
-4. **Replace taglib methodMissing dispatch** - `TagLibraryMetaUtils.methodMissingForTagLib` resolves tags dynamically. Generate a dispatch table `Map<String, Closure>` at startup.
-5. **Add a metaclass modification freeze** - After startup, set a flag that prevents (or logs warnings for) any further metaclass modifications. This makes violations detectable.
-
-**Priority**: **P0** - 4x performance regression significantly impacts user experience and adoption.
-**Effort**: High (requires systematic audit and rewrite of metaclass modification patterns across GORM, codecs, and taglibs)
-
----
-
-### 1.2 Spring AOT Integration
-
-**Current state**: Zero Spring AOT support. No `RuntimeHints`, no `AotProcessor`, no `BeanRegistrationAotProcessor`, no `spring-context-indexer`.
-
-**What Spring AOT gives for free** (if integrated):
-- Ahead-of-time bean definition generation (no runtime reflection for bean wiring)
-- Compile-time proxy generation (no CGLIB at runtime)
-- Reflection metadata pre-computation
-- GraalVM native image readiness (prerequisite)
-- 30-40% startup time reduction
-
-**Required work**:
-1. Implement `BeanFactoryInitializationAotProcessor` for Grails plugin `doWithSpring` closures
-2. Implement `BeanRegistrationAotProcessor` for artefact beans (controllers, services, taglibs)
-3. Generate `RuntimeHints` for all unavoidable reflection (domain classes, command objects, config binding)
-4. Add `spring-context-indexer` support - generate `META-INF/spring.components` at build time to eliminate runtime classpath scanning
-
-**Priority**: **P0** - Prerequisite for GraalVM native image and major startup improvement.
-**Effort**: Very High (new subsystem, touches bean lifecycle fundamentals)
-
----
-
-### 1.3 Virtual Thread Readiness
-
-**Current state**: Multiple `ThreadLocal` usages that will break with virtual threads:
-
-| Location | Usage | Severity |
-|----------|-------|----------|
-| `ChainedEncoder` (grails-encoder) | ThreadLocal for encoder caching | High - per-request encoding |
-| `DatastoreUtils` (grails-datastore-core) | NamedThreadLocal for deferred session close | High - every GORM operation |
-| `SoftThreadLocalMap` (grails-datastore-core) | InheritableThreadLocal for session map | High - session management |
-| `ConvertersConfigurationHolder` (grails-converters) | ThreadLocal for converter config | Medium - JSON/XML rendering |
-| `Tenants` (grails-datamapping-core) | ThreadLocal for current tenant ID | High - multi-tenancy |
-| `DeferredBindingActions` (grails-core) | ThreadLocal for binding action queue | Medium - data binding |
-| `GroovyPageMetaInfo` (grails-gsp) | ThreadLocal for page instances | Medium - GSP rendering |
-
-**Why this matters**: Spring Boot 4 and Spring Framework 7 have first-class virtual thread support. Spring Boot 4 auto-configures virtual threads when available on Java 21+. If Grails' ThreadLocal usage pins virtual threads to platform threads, users get worse performance than Grails 7 when enabling virtual threads.
-
-**Required work**:
-1. Audit ALL ThreadLocal/InheritableThreadLocal usages across the codebase
-2. Replace with `ScopedValue` (Java 21+ preview, Java 25 final) where possible
-3. For Java 17 baseline: replace with request-scoped beans or explicit context propagation
-4. Test under virtual thread executor to verify no pinning
-
-**Priority**: **P1** - Java 21 virtual threads are the biggest JVM performance improvement in a decade. Grails must not regress.
-**Effort**: Medium (systematic but each replacement is straightforward)
-
----
-
-### 1.4 Static Compilation Coverage Expansion
-
-**Current state in grails-core/src/main**: 45 out of 73 Groovy files (62%) have `@CompileStatic` or `@GrailsCompileStatic`.
-
-Without `@CompileStatic`, every Groovy method call goes through dynamic dispatch:
-- MetaClass lookup per call
-- No JIT inlining
-- Indy call site caching defeated by metaclass changes (ties into 1.1)
-- GraalVM native image impossible for dynamically-dispatched code
-
-**Required work**:
-1. Audit all `.groovy` files in `src/main` across every module for `@CompileStatic` eligibility
-2. Add `@CompileStatic` to all artefact handlers (simple suffix-matching, pure static logic)
-3. Add `@CompileStatic` to all utility classes (`GrailsNameUtils`, `GrailsClassUtils` - already type-safe)
-4. Add `@CompileStatic` to all configuration classes
-5. Create a `compileStaticCheck` Gradle task that fails on new Groovy files without `@CompileStatic` (unless explicitly exempted with `@CompileStatic(TypeCheckingMode.SKIP)`)
-
-**Target**: 90%+ static compilation across framework source by Grails 8 GA.
-
-**Modules with highest opportunity**:
-
-| Module | Estimated Eligible | Currently Static |
-|--------|-------------------|-----------------|
-| grails-web-url-mappings | ~15 files | ~2 |
-| grails-converters | ~10 files | ~0 |
-| grails-controllers | ~8 files | ~3 |
-| grails-validation | ~8 files | ~3 |
-| grails-interceptors | ~6 files | ~1 |
-| grails-databinding | ~6 files | ~2 |
-| grails-services | ~5 files | ~1 |
-| grails-mimetypes | ~5 files | ~1 |
-
-**Priority**: **P1** - Direct performance impact, enables GraalVM, prevents Indy regression.
-**Effort**: Medium (systematic, most files need only annotation addition + minor type fixes)
-
----
-
-### 1.5 Artefact Discovery at Build Time
-
-**Current state**: Runtime scanning via `ArtefactHandler.isArtefact(Class)` for every application class at startup.
-
-**Required work**:
-1. Generate `META-INF/grails/artefact-index.properties` at build time (Gradle plugin or annotation processor)
-2. Extend existing AST transforms (`ControllerArtefactTypeTransformation`, `TagLibArtefactTypeAstTransformation`) to write index entries
-3. `DefaultGrailsApplication.configureLoadedClasses()` reads the pre-built index instead of iterating all handlers
-4. Fall back to runtime scanning only for classes not in the index (backward compat)
-
-**Priority**: **P1** - 10-15% startup reduction, enables Spring AOT integration.
-**Effort**: Medium
-
----
-
-## Tier 2 - Security Hardening
-
-### 2.1 Default Security Headers
-
-**Current state**: Grails does not set modern security headers out of the box. Applications must configure these manually or rely on the Spring Security plugin.
-
-**Required defaults for Grails 8**:
-
-| Header | Value | Purpose |
-|--------|-------|---------|
-| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains` | Force HTTPS |
-| `X-Content-Type-Options` | `nosniff` | Prevent MIME sniffing |
-| `X-Frame-Options` | `DENY` | Prevent clickjacking |
-| `Content-Security-Policy` | `default-src 'self'` (configurable) | Prevent XSS/injection |
-| `Referrer-Policy` | `strict-origin-when-cross-origin` | Limit referrer leakage |
-| `Permissions-Policy` | Deny camera, microphone, geolocation by default | Limit browser API abuse |
-| `X-XSS-Protection` | `0` (modern approach - let CSP handle it) | Disable buggy browser XSS filter |
-
-**Implementation**: Add a `SecurityHeadersFilter` registered by default in `ControllersAutoConfiguration`. Allow full override via `application.yml` under `grails.security.headers.*`. Disable with `grails.security.headers.enabled: false`.
-
-**Priority**: **P1** - Security defaults should be secure. Opt-out, not opt-in.
-**Effort**: Low
-
----
-
-### 2.2 CSRF Protection by Default
-
-**Current state**: No built-in CSRF protection. Entirely delegated to Spring Security plugin (optional dependency).
-
-**Potentially for Grails 8**:
-- Enable CSRF token generation and validation for all state-changing requests (POST, PUT, DELETE, PATCH) by default
-- Integrate with Spring Security's `CsrfFilter` when Spring Security is present
-- Provide standalone CSRF filter when Spring Security is NOT present
-- Add GSP tag `<g:csrfToken/>` or auto-inject into `<g:form>` tags
-- Support both synchronizer token pattern and double-submit cookie pattern
-- Support SPA/API mode with `X-CSRF-TOKEN` header
-
-**Priority**: **P1** - OWASP Top 10. Should not require a plugin.
-**Effort**: Medium
-
----
-
-### 2.3 Secure Data Binding (`secureBindData()`)
-
-**Current state**: `bindData()` supports `whiteList`/`blackList` parameters via `DefaultASTDatabindingHelper` compile-time generation, but there is no enforcement that callers provide an explicit allowed params list. Omitting the list silently binds all request parameters - a mass-assignment vulnerability.
-
-**Two new binding methods for Grails 8**:
-
-| Method | Behavior | Use Case |
-|--------|----------|----------|
-| `secureBindData(target, params, allowedParams)` | Binds only properties in `allowedParams`. **Compile error if `allowedParams` is omitted.** | Standard secure binding - prevents mass-assignment by requiring an explicit allowlist |
-| `secureBindData(target, params, allowedParams, nullMissing: true)` | Binds properties in `allowedParams`. Properties that are in `allowedParams` but **missing from the request** are set to `null` on the target. | Prevents stale data attacks - ensures an update form that omits a field actually clears that field, rather than preserving whatever value was previously persisted |
-
-**Example**:
-
-```groovy
-// Compile error - allowedParams required
-secureBindData(book, params)  // FAILS
-
-// Only title and author are bound; all other params ignored
-secureBindData(book, params, ['title', 'author'])
-
-// title bound from params; author is in allowed list but missing
-// from request, so book.author is set to null
-secureBindData(book, params, ['title', 'author'], nullMissing: true)
-```
-
-**Implementation**: AST transform enforces the `allowedParams` parameter at compile time. The `nullMissing` variant iterates the allowed list after binding and sets any property not present in the request params to `null`.
-
-**Priority**: **P1** - Mass-assignment is OWASP Top 10. Secure binding should be easy to use correctly.
-**Effort**: Medium
-
----
-
-### 2.4 Encode-by-Default in GSP
-
-**Current state**: GSP has codec-aware output, but the default encoding behavior varies. `${expression}` output encoding depends on the codec configured for the page.
-
-**Potentially for Grails 8**:
-- Default all GSP expression output to HTML encoding (`encodeAsHTML()`)
-- Require explicit `raw()` or `${raw(expression)}` for unencoded output
-- Add compile-time warnings for `raw()` usage (via AST transform or CodeNarc rule)
-- Ensure JSON views default to proper JSON encoding
-
-**Priority**: **P1** - XSS is OWASP #1. Encode by default is industry standard.
-**Effort**: Low (GSP already has codec infrastructure; this is a default-change + audit)
-
----
-
-### 2.5 Dependency Vulnerability Scanning in Build
-
-**Current state**: CycloneDX SBOM generation exists (`gradleCycloneDxPluginVersion=2.4.1`) but no automated vulnerability scanning in CI.
-
-**Potentially for Grails 8**:
-- Add OWASP Dependency-Check or Gradle's built-in dependency verification to CI
-- Document known CVE exposure in release notes
-- Pin transitive dependencies that have known CVEs
-- Consider adopting Gradle's dependency locking for reproducible builds
-
-**Priority**: **P2** - Supply chain security is table stakes for enterprise adoption.
-**Effort**: Low
-
----
-
-### 2.6 GORM Query Safety Audit
-
-**Current state**: GORM's HQL/`@Query` support accepts string interpolation in queries. Dynamic finders are safe by design (parameterized). But `executeQuery()`, `executeUpdate()`, and `@Query` with GString interpolation can produce SQL injection.
-
-**Potentially for Grails 8**:
-- Add compile-time warning for GString-interpolated HQL queries (AST transform or type checking extension)
-- Document safe query patterns prominently
-- Consider deprecating `executeQuery(String)` in favor of parameterized-only API
-- Audit all internal GORM query construction for injection vectors
-
-**Priority**: **P2** - SQL injection is OWASP #3. Framework should make the safe path the easy path.
-**Effort**: Medium
-
----
-
-## Tier 3 - Modern Runtime Features
-
-### 3.1 Observability (OpenTelemetry / Micrometer)
-
-**Current state**: Basic Micrometer integration exists through Spring Boot autoconfiguration. No Grails-specific metrics, traces, or spans.
-
-**Potentially for Grails 8**:
-- Auto-instrument GORM operations (query timing, cache hits, connection pool stats)
-- Auto-instrument controller actions (request timing, status codes, exception types)
-- Auto-instrument interceptor chain execution
-- Auto-instrument GSP rendering time
-- Support OpenTelemetry trace context propagation through GORM operations and async calls
-- Expose Grails-specific health indicators (plugin status, artefact counts, GORM session stats)
-
-**Implementation**: Use Micrometer's `ObservationRegistry` (Spring Framework 6.1+/7.0). Add `@Observed` or manual `Observation.start()` at key framework extension points.
-
-**Priority**: **P1** - Observability is common in modern frameworks and increasingly expected by enterprise users.
-**Effort**: Medium
-
----
-
-### 3.2 HTTP Interface Clients
-
-**Current state**: No built-in HTTP client abstraction. Applications use `RestTemplate`, `WebClient`, or third-party libraries directly.
-
-**Spring Framework 7** introduces `@HttpExchange` interface clients - declare an interface with annotated methods, and Spring generates the implementation.
-
-**Potentially for Grails 8**:
-- Auto-configure `HttpServiceProxyFactory` for `@HttpExchange` interfaces
-- Support `@HttpExchange` interface scanning in `src/main/groovy`
-- Add GORM-style convention support (optional): `BookClient` interface in `clients/` directory auto-configured
-- Document migration from `RestTemplate` to `@HttpExchange`
-
-**Priority**: **P2** - Nice-to-have for Grails 8.0, but aligns with Grails' convention-based philosophy.
-**Effort**: Low (leverage Spring's existing implementation)
-
----
-
-### 3.3 Structured Logging
-
-**Current state**: Standard SLF4J logging. No structured logging support.
-
-**Potentially for Grails 8**:
-- Support structured logging output (JSON format) via configuration
-- Auto-add request context (requestId, sessionId, userId) to MDC
-- Auto-add GORM context (datasource, tenant) to MDC
-- Support Spring Boot 4's structured logging configuration
-- Correlation ID propagation across async operations
-
-**Priority**: **P2** - Required for cloud-native deployments with log aggregation.
-**Effort**: Low
-
----
-
-## Tier 4 - Compile-Time Shift
-
-> These items are detailed in `GRAILS8-COMPILE-TIME-OPPORTUNITIES.md`. This section prioritizes
-> them in the context of the full Grails 8 roadmap and adjusts priorities based on what's
-> realistic for the 8.0.x timeline vs. 8.1+.
-
-### 4.1 Eliminate ExpandoMetaClass from Hot Paths (8.0.x)
-
-**185+ usages across 57 files.** The biggest source of Indy regression, GraalVM incompatibility, and startup overhead.
-
-**8.0.x scope** (most impactful, manageable effort):
-1. Replace `CodecMetaClassSupport` EMC methods with Groovy extension modules
-2. Replace `TagLibraryMetaUtils.methodMissing` with startup-built dispatch table
-3. Batch all GORM `GormEnhancer.enhance()` metaclass modifications to startup
-4. Replace `HttpServletRequestExtension.propertyMissing` with extension methods
-5. Replace `HttpSessionExtension.propertyMissing` with extension methods
-
-**8.1+ scope** (requires Groovy 5 features, deeper changes):
-- Replace GORM dynamic finders with AST-generated static methods
-- Replace `HibernateMappingBuilder.methodMissing` DSL with `@DelegatesTo` typed builder
-- Replace `NamedCriteriaProxy.methodMissing` with generated methods
-
-**Priority**: **P1** for 8.0.x scope, **P2** for deeper changes.
-**Effort**: High overall, but individual replacements are well-scoped
-
----
-
-### 4.2 URL Mapping Pre-computation (8.0.x)
-
-**Current state**: All URL mappings are evaluated from Groovy closures at startup, then matched via linear iteration + regex per request.
-
-**8.0.x scope**:
-1. Pre-compile URL mapping patterns at build time, output `META-INF/grails/url-mappings.json`
-2. Replace linear matching with trie-based routing (O(path_length) vs O(num_mappings))
-3. Pre-compute reverse routing tables for link generation
-
-**Priority**: **P1** - Direct per-request latency improvement for every Grails app.
-**Effort**: High
-
----
-
-### 4.3 Data Binding Code Generation (8.1+)
-
-Replace reflection-based `BeanWrapper` property binding with AST-generated type-safe binders. 89+ usages of `BeanWrapper`/`BeanWrapperImpl` across 33 files.
-
-**Priority**: **P2** - Important for GraalVM and startup, but large effort.
-**Effort**: Very High
-
----
-
-### 4.4 GrailsNameUtils Pre-computation (8.0.x)
-
-80+ files call `GrailsNameUtils` for convention name resolution at runtime. These are pure string functions called thousands of times.
-
-**8.0.x scope**: Extend artefact AST transforms to generate `GRAILS_LOGICAL_NAME`, `GRAILS_PROPERTY_NAME` constants on each artefact class. Framework reads constants instead of computing.
-
-**Priority**: **P2** - Moderate startup improvement, easy win.
-**Effort**: Medium
-
----
-
-### 4.5 Plugin Loading Optimization (8.0.x)
-
-Generate `META-INF/grails/plugin-registry.properties` at build time with plugin classes and pre-computed dependency order. Eliminates runtime classpath scanning and topological sorting.
-
-**Priority**: **P2** - 5-10% startup improvement.
-**Effort**: Medium
-
----
-
-## Tier 5 - Developer Experience
-
-### 5.1 JLine 3 CLI Modernization
-
-**PR**: [#15367](https://github.com/apache/grails-core/pull/15367) (ready)
-
-Upgrades from EOL JLine 2 to JLine 3, with 100+ new test cases, improved completion, and better terminal handling. JLine 2 dependency retained only for Groovy 4.x groovysh; removable after Groovy 5.
-
-#### PR #15367 Changes
-
-| Category | Change | Files |
-|----------|--------|-------|
-| **JLine 2 to 3 core migration** | `jline.console.ConsoleReader` to `org.jline.reader.LineReader` / `org.jline.terminal.Terminal` | `GrailsConsole.java` (108 lines changed), `GrailsCli.groovy` |
-| **Terminal creation** | Direct `ConsoleReader()` to `TerminalBuilder.builder().build()` + `LineReaderBuilder` | `GrailsConsole.java` |
-| **Completer API migration** | All completers: `complete(String, int, List<CharSequence>)` to `complete(LineReader, ParsedLine, List<Candidate>)` | `StringsCompleter`, `RegexCompletor`, `EscapingFileNameCompletor`, `SimpleOrFileNameCompletor`, `ClosureCompleter`, `CommandCompleter`, `SortedAggregateCompleter` (7 files) |
-| **Candidate objects** | `CharSequence` candidates replaced with `Candidate` objects (full names for flags, profiles, features) | All completer classes |
-| **AggregateCompleter** | Supports multiple completers in GrailsConsole | `SortedAggregateCompleter.java` |
-| **History handling** | Attached to LineReader via builder instead of separate ConsoleReader API | `GrailsConsole.java`, `GrailsCli.groovy` |
-| **Dumb terminal detection** | `"dumb".equals(terminal.getType())` | `GrailsConsole.java` |
-| **Efficient completer updates** | `updateCompleter()` instead of rebuilding LineReader | `GrailsConsole.java` |
-| **Auto-complete common prefix** | `CandidateListCompletionHandler` auto-completes common prefix in buffer | `CandidateListCompletionHandler.java` |
-| **CTRL+C handling** | Better cancellation via terminal interrupt masking and keypress polling | `GrailsConsole.java` |
-| **Dependency versions** | `jline: 3.30.6`, `jansi: 2.4.2`, added `jline2: 2.14.6` for Groovy 4 compat | `dependencies.gradle` |
-| **New test coverage** | 8 new spec files, 100+ test cases | `StringsCompleterSpec` (20+), `SortedAggregateCompleterSpec` (10), `ClosureCompleterSpec` (8), `EscapingFileNameCompletorSpec` (10), `SimpleOrFileNameCompletorSpec` (12), `CommandCompleterSpec` (12), `CandidateListCompletionHandlerSpec` (20+), `GrailsConsoleCompleterSpec` (15+) |
-| **Enhanced existing tests** | Edge case coverage added | `RegexCompletorSpec` (10+ new cases) |
-
-#### PR #15367 Workarounds
-
-| Workaround | Reason | Removal Path |
-|------------|--------|--------------|
-| JLine 2 (`jline:jline:2.14.6`) retained as dependency | Groovy 4.x `groovysh` module requires JLine 2 | **Remove after Groovy 5 merge** (PR #15183) - Groovy 5 drops JLine 2. Both coexist safely (different package namespaces: `jline.*` vs `org.jline.*`) |
-| TODO comments marking JLine 2 deps | Breadcrumbs for cleanup | Remove when JLine 2 is removed |
-
-#### PR #15367 Open Decisions
-
-| Decision | Context | Options |
-|----------|---------|---------|
-| **JLine 2 removal timing** | Only needed for Groovy 4.x groovysh. Once Groovy 5 lands, removable. | (a) Remove in same release as Groovy 5, (b) Keep one release for backward compat |
-| **Eclipse console support** | `GrailsEclipseConsole` updated minimally. Eclipse/STS Grails support is effectively unmaintained. | (a) Keep minimal support, (b) Deprecate in 8.0, remove in 8.1 |
-
-**Priority**: **P1** - CLI is the first thing developers touch.
-**Effort**: Done (PR exists)
-
----
-
-### 5.2 Improved Error Messages and Diagnostics
-
-**Current state**: Many framework errors produce stack traces that point to internal framework code, not user code. GORM dynamic finder typos (`Book.findByTitel("...")`) fail at runtime with `MissingMethodException`.
-
-**Potentially for Grails 8**:
-- Add compile-time validation of dynamic finder property names (AST type checking extension)
-- Improve controller action not-found messages (suggest closest match)
-- Add URL mapping validation at startup (report conflicts, unreachable mappings)
-- Add plugin compatibility checker at startup (report version mismatches)
-
-**Priority**: **P2**
-**Effort**: Medium
-
----
-
-### 5.3 Configuration Documentation and Validation
-
-**PR**: [#15426](https://github.com/apache/grails-core/pull/15426) (hybrid ConfigReportCommand)
-**PR**: [#15407](https://github.com/apache/grails-core/pull/15407) (configuration reference docs)
-
-These PRs add ~160 documented configuration properties with descriptions and defaults. Grails 8 should ship with:
-- Built-in configuration validation at startup (warn on unknown properties)
-- IDE-friendly configuration metadata (`META-INF/spring-configuration-metadata.json`)
-- `grails config-report` command for runtime configuration inspection
-
-**Priority**: **P2**
-**Effort**: Low (PRs in progress)
-
----
-
-### 5.4 Continuous Testing Mode
-
-**What Quarkus offers**: Automatic re-run of affected tests when source changes are detected.
-
-**What Grails 8 should add**:
-- Leverage Gradle's continuous build (`--continuous`) with smarter test filtering
-- Add `grails test-app --watch` that re-runs only affected tests
-- Integrate with Gradle's test retry plugin for flaky test mitigation
-
-**Priority**: **P3** - Nice to have, not blocking.
-**Effort**: Medium
-
----
-
-## Tier 6 - Ecosystem and Future-Proofing
-
-### 6.1 GraalVM Native Image Support
-
-**Current state**: Zero support in framework (grails-forge has some reflect-config.json for Micronaut-based forge app only). No `RuntimeHints`, no native-image.properties in any framework module.
-
-**Dependency chain**: This requires Tier 0 (Spring Boot 4), Tier 1.2 (Spring AOT), Tier 1.4 (static compilation), and Tier 4.1 (ExpandoMetaClass elimination). It is NOT achievable in 8.0.x.
-
-**8.1+ roadmap**:
-1. Complete Spring AOT integration
-2. Generate `RuntimeHints` for all remaining reflection
-3. Eliminate or hint all `Class.forName` calls (48+ in production code)
-4. Test full Grails app under GraalVM native image
-5. Publish native image configuration as part of build artifacts
-
-**Priority**: **P2** for 8.0.x preparation, **P1** for 8.1.
-**Effort**: Very High (depends on Tiers 0-4)
-
----
-
-### 6.2 JPMS Module System Readiness
-
-**Current state**: Zero `module-info.java` files. No automatic module names in manifests.
-
-**Potentially for Grails 8**:
-1. Add `Automatic-Module-Name` manifest entries to all published JARs (non-breaking, enables modular consumers)
-2. Plan `module-info.java` files for 8.1+ (breaking for split package issues)
-
-**Priority**: **P3** - Modular JDK adoption is slow but accelerating.
-**Effort**: Low for automatic module names, High for full JPMS
-
----
-
-### 6.3 Subproject Dependency Cleanup
-
-**Current state**: Mixed dependency versions across subprojects. `grails-data-neo4j` targets Java 11 with Hibernate 5.5.7. `grails-data-graphql/core` targets Java 8. `grails-forge` uses Micronaut 3.10.4 (upgraded to 4 in [#15365](https://github.com/apache/grails-core/pull/15365)).
-
-**Potentially for Grails 8**:
-- Unify Java baseline to 17 across ALL modules (drop Java 8/11 compat in neo4j and graphql)
-- Align all Hibernate versions
-- Align all Spock versions
-- Consider version catalog (`libs.versions.toml`) for centralized dependency management
-
-**Priority**: **P2** - Reduces maintenance burden and dependency conflicts.
-**Effort**: Medium
-
----
-
-### 6.4 Multi-Datasource and Multi-Tenant Robustness
-
-**Active work on 7.0.x**: PRs [#15425](https://github.com/apache/grails-core/pull/15425) (OSIV for all datasources), [#15429](https://github.com/apache/grails-core/pull/15429) (TCK data service connection routing), [#15423](https://github.com/apache/grails-core/pull/15423) (@Query connection routing tests).
-
-These fixes and tests should merge into 8.0.x. Multi-datasource and multi-tenant are enterprise requirements that need to be rock-solid.
-
-**Priority**: **P1** - Enterprise feature that's currently buggy.
-**Effort**: Low (work already in progress on 7.0.x, merge forward)
-
----
-
-## What NOT to Do in Grails 8
-
-| Temptation | Why Not | Instead |
-|------------|---------|---------|
-| Full GORM dynamic finder compilation | Too large for 8.0.x, risk of breaking backward compat | Batch metaclass mods at startup (1.1), generate in 8.1+ |
-| Drop Groovy dynamic features entirely | Breaks Grails' identity and existing apps | Static-by-default, dynamic-by-choice |
-| Rewrite GSP from scratch | Massive effort, uncertain payoff | Enforce pre-compilation, improve encoding defaults |
-| Add reactive/R2DBC stack | Fragmentary ecosystem, Loom makes it unnecessary | Virtual thread support (1.3) is the modern answer |
-| Full microservices framework | Not Grails' niche; that's Micronaut's territory | Focus on what Grails does best - productive full-stack web |
-| Drop Hibernate 5.6 support immediately | Many apps can't upgrade overnight | Ship with Hibernate 7 default, keep 5.6-jakarta as opt-in for 8.0.x. Hibernate 6 module removed (stepping stone only). |
-| Implement custom DI container | Spring is Grails' foundation, not a liability | Leverage Spring AOT, don't compete with it |
-| Chase every Java 25 feature | Java 17 is the baseline; don't fragment | Target 17 baseline, 21 recommended, 25 tested |
-
----
-
-## Priority Summary Matrix
-
-| # | Item | Tier | Priority | Effort | Release |
-|---|------|------|----------|--------|---------|
-| 0.1 | Spring Boot 4 + Spring Framework 7 | Gate | CRITICAL | Medium | 8.0.0-M1 |
-| 0.2 | Groovy 5 Compatibility | Gate | CRITICAL | High | 8.0.0-M1 |
-| 0.3 | Hibernate 7 Support | Gate | CRITICAL | Very High | 8.0.0-M2 |
-| 0.4 | Gradle 9 Support | Gate | CRITICAL | Low | 8.0.0-M1 |
-| 0.5 | Bean Builder Rework | Gate | CRITICAL | High | 8.0.0-M2 |
-| 1.1 | Fix Indy 4x Regression | Perf | P0 | High | 8.0.0-M1 |
-| 1.2 | Spring AOT Integration | Perf | P0 | Very High | 8.0.0-RC |
-| 1.3 | Virtual Thread Readiness | Perf | P1 | Medium | 8.0.0-M2 |
-| 1.4 | Static Compilation Expansion | Perf | P1 | Medium | 8.0.0-M2 |
-| 1.5 | Artefact Discovery at Build Time | Perf | P1 | Medium | 8.0.0-RC |
-| 2.1 | Default Security Headers | Security | P1 | Low | 8.0.0-M1 |
-| 2.2 | CSRF Protection by Default | Security | P1 | Medium | 8.0.0-M2 |
-| 2.3 | Secure Data Binding (`secureBindData()`) | Security | P1 | Medium | 8.0.0-M2 |
-| 2.4 | Encode-by-Default in GSP | Security | P1 | Low | 8.0.0-M1 |
-| 2.5 | Dependency Vulnerability Scanning | Security | P2 | Low | 8.0.0-M1 |
-| 2.6 | GORM Query Safety Audit | Security | P2 | Medium | 8.0.0-RC |
-| 3.1 | Observability (OTel/Micrometer) | Runtime | P1 | Medium | 8.0.0-RC |
-| 3.2 | HTTP Interface Clients | Runtime | P2 | Low | 8.0.x |
-| 3.3 | Structured Logging | Runtime | P2 | Low | 8.0.0-M2 |
-| 4.1 | Eliminate ExpandoMetaClass Hot Paths | Compile | P1 | High | 8.0.0-RC |
-| 4.2 | URL Mapping Pre-computation | Compile | P1 | High | 8.1.x |
-| 4.3 | Data Binding Code Generation | Compile | P2 | Very High | 8.1.x |
-| 4.4 | GrailsNameUtils Pre-computation | Compile | P2 | Medium | 8.0.x |
-| 4.5 | Plugin Loading Optimization | Compile | P2 | Medium | 8.0.x |
-| 5.1 | JLine 3 CLI | DX | P1 | Done | 8.0.0-M1 |
-| 5.2 | Improved Error Messages | DX | P2 | Medium | 8.0.x |
-| 5.3 | Configuration Docs/Validation | DX | P2 | Low | 8.0.0-M2 |
-| 5.4 | Continuous Testing Mode | DX | P3 | Medium | 8.1.x |
-| 6.1 | GraalVM Native Image | Future | P2 | Very High | 8.1.x |
-| 6.2 | JPMS Module System | Future | P3 | Low-High | 8.0.x-8.1.x |
-| 6.3 | Subproject Dependency Cleanup | Future | P2 | Medium | 8.0.0-M1 |
-| 6.4 | Multi-Datasource Robustness | Future | P1 | Low | 8.0.0-M1 |
-
----
-
-## Appendix: Competitive Landscape
-
-### What Grails 8 Must Match
-
-| Feature | Spring Boot 4 | Micronaut 4 | Quarkus 3 | Grails 8 Status |
-|---------|--------------|-------------|-----------|-----------------|
-| AOT compilation | Full Spring AOT | Core architecture | Core architecture | **Zero** - needs 1.2 |
-| GraalVM native | Supported + tested | Supported + tested | Supported + tested | **Zero** - needs 6.1 |
-| Virtual threads | Auto-configured | Supported | Supported | **Broken** - needs 1.3 |
-| Startup time (simple app) | ~1s | ~0.5s | ~0.3s | **~3-5s** - needs Tier 1 |
-| Security headers | Spring Security defaults | Manual | Built-in | **None** - needs 2.1 |
-| CSRF protection | Spring Security | Manual | Built-in | **None** - needs 2.2 |
-| Observability | Micrometer + OTel | Micrometer + OTel | MicroProfile + OTel | **Basic** - needs 3.1 |
-| Structured logging | Built-in (Boot 3.4+) | Built-in | Built-in | **None** - needs 3.3 |
-| HTTP clients | @HttpExchange | @Client | REST Client | **None** - needs 3.2 |
-| Build-time DI | Partial (AOT) | Full | Full | **None** - needs 1.2 |
-| Static compilation | N/A (Java) | Default | Default | **62%** - needs 1.4 |
-
-### Grails' Competitive Advantages to Preserve
-
-| Strength | Description | Don't Break It |
-|----------|-------------|----------------|
-| Convention over configuration | Artefact-based development with zero boilerplate | Keep conventions, just make them compile-time |
-| GORM | Most productive ORM in the JVM ecosystem | Fix Indy regression, don't rewrite |
-| GSP + Views | Server-side rendering that just works | Improve encoding, don't replace |
-| Plugin ecosystem | Rich library of community plugins | Bean Builder rework must be backward-compatible |
-| Groovy productivity | Dynamic when you want, static when you need | Static-by-default, dynamic-by-choice |
-| Full-stack simplicity | One framework for everything | Don't fragment into microservices pieces |
\ No newline at end of file
diff --git a/grails-data-hibernate7/build-full.csv b/grails-data-hibernate7/build-full.csv
deleted file mode 100644
index 932c165c11..0000000000
--- a/grails-data-hibernate7/build-full.csv
+++ /dev/null
@@ -1,415 +0,0 @@
-fully_qualified_class,line_number,rule,message
-grails.orm.CriteriaMethodInvoker,109,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'ignoreCase' (lines '109'-'112').
-grails.orm.CriteriaMethodInvoker,154,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'hibernateQuery' (lines '154'-'201').
-grails.orm.CriteriaMethodInvoker,156,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'callable' (lines '156'-'201').
-grails.orm.CriteriaMethodInvoker,157,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'joinType' (lines '157'-'190').
-grails.orm.CriteriaMethodInvoker,157,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'joinType' (lines '157'-'201').
-grails.orm.CriteriaMethodInvoker,208,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'value' (lines '208'-'231').
-grails.orm.CriteriaMethodInvoker,210,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'hibernateQuery' (lines '210'-'231').
-grails.orm.CriteriaMethodInvoker,220,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'propertyName' (lines '220'-'231').
-grails.orm.CriteriaMethodInvoker,238,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'propertyName' (lines '238'-'292').
-grails.orm.CriteriaMethodInvoker,243,AvoidLiteralsInIfCondition,Avoid using Literals in Conditional Statements
-grails.orm.HibernateCriteriaBuilder,101,AvoidFieldNameMatchingMethodName,Field scroll has the same name as a method
-grails.orm.HibernateCriteriaBuilder,102,AvoidFieldNameMatchingMethodName,Field count has the same name as a method
-grails.orm.HibernateCriteriaBuilder,114,AvoidFieldNameMatchingMethodName,Field readOnly has the same name as a method
-grails.orm.HibernateCriteriaBuilder,115,AvoidFieldNameMatchingMethodName,Field distinct has the same name as a method
-grails.orm.HibernateCriteriaBuilder,117,AvoidDuplicateLiterals,"The String literal ""rawtypes"" appears 16 times in this file; the first occurrence is on line 117"
-grails.orm.HibernateCriteriaBuilder,121,ConstructorCallsOverridableMethod,Overridable method 'setDatastore' called during object construction
-grails.orm.HibernateCriteriaBuilder,128,ConstructorCallsOverridableMethod,Overridable method 'setDefaultFlushMode' called during object construction
-grails.orm.HibernateCriteriaBuilder,504,AvoidDuplicateLiterals,"The String literal ""unchecked"" appears 5 times in this file; the first occurrence is on line 504"
-grails.orm.HibernateCriteriaBuilder,855,CompareObjectsWithEquals,Use equals() to compare object references.
-grails.orm.HibernateCriteriaBuilder,1213,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.AbstractHibernateDatastore,112,AvoidFieldNameMatchingMethodName,Field isCacheQueries has the same name as a method
-org.grails.orm.hibernate.AbstractHibernateDatastore,137,CloseResource,Ensure that resources like this HibernateConnectionSource object are closed after use
-org.grails.orm.hibernate.AbstractHibernateDatastore,265,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.AbstractHibernateDatastore,460,CloseResource,Ensure that resources like this AbstractHibernateDatastore object are closed after use
-org.grails.orm.hibernate.AbstractHibernateDatastore,461,CloseResource,Ensure that resources like this SessionFactory object are closed after use
-org.grails.orm.hibernate.AbstractHibernateDatastore,499,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'multiTenantCallable' (lines '499'-'515').
-org.grails.orm.hibernate.AbstractHibernateDatastore,499,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'multiTenantCallable' (lines '499'-'515').
-org.grails.orm.hibernate.AbstractHibernateSession,107,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.EventListenerIntegrator,82,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'listenerRegistry' (lines '82'-'103').
-org.grails.orm.hibernate.EventListenerIntegrator,87,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'type' (lines '87'-'87').
-org.grails.orm.hibernate.EventListenerIntegrator,87,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'type' (lines '87'-'103').
-org.grails.orm.hibernate.EventListenerIntegrator,98,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'listenerMap' (lines '98'-'103').
-org.grails.orm.hibernate.EventListenerIntegrator,108,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'group' (lines '108'-'122').
-org.grails.orm.hibernate.GrailsHibernateTemplate,135,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'previousHolder' (lines '135'-'221').
-org.grails.orm.hibernate.GrailsHibernateTemplate,136,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'previousConnectionHolder' (lines '136'-'221').
-org.grails.orm.hibernate.GrailsHibernateTemplate,138,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.GrailsHibernateTemplate,138,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'newSession' (lines '138'-'164').
-org.grails.orm.hibernate.GrailsHibernateTemplate,141,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'transactionSynchronizations' (lines '141'-'221').
-org.grails.orm.hibernate.GrailsHibernateTemplate,191,CloseResource,Ensure that resources like this Connection object are closed after use
-org.grails.orm.hibernate.GrailsHibernateTemplate,303,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.GrailsHibernateTemplate,309,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'previousFlushMode' (lines '309'-'311').
-org.grails.orm.hibernate.GrailsHibernateTemplate,311,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'previousFlushMode' (lines '311'-'343').
-org.grails.orm.hibernate.GrailsHibernateTemplate,348,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.GrailsHibernateTemplate,382,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.GrailsHibernateTemplate,539,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.GrailsHibernateTemplate,683,EmptyIfStmt,Avoid empty if statements
-org.grails.orm.hibernate.GrailsSessionContext,136,EmptyIfStmt,Avoid empty if statements
-org.grails.orm.hibernate.GrailsSessionContext,146,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.GrailsSessionContext,191,EmptyIfStmt,Avoid empty if statements
-org.grails.orm.hibernate.GrailsSessionContext,199,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.GrailsSessionContext,202,AvoidCatchingThrowable,A catch statement should never catch throwable since it includes errors.
-org.grails.orm.hibernate.GrailsSessionContext,209,CloseResource,Ensure that resources like this SessionFactoryImplementor object are closed after use
-org.grails.orm.hibernate.GrailsSessionContext,209,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'sessionFactoryImpl' (lines '209'-'211').
-org.grails.orm.hibernate.GrailsSessionContext,209,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'sessionFactoryImpl' (lines '209'-'215').
-org.grails.orm.hibernate.GrailsSessionContext,213,CloseResource,Ensure that resources like this SessionFactory object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,111,ConstructorCallsOverridableMethod,"Overridable method 'getMetadata' called during object construction (call stack: [getMetadataInternal, getMetadata])"
-org.grails.orm.hibernate.HibernateDatastore,113,CloseResource,Ensure that resources like this HibernateConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,131,ConstructorCallsOverridableMethod,Overridable method 'registerEventListeners' called during object construction
-org.grails.orm.hibernate.HibernateDatastore,132,ConstructorCallsOverridableMethod,Overridable method 'configureValidatorRegistry' called during object construction
-org.grails.orm.hibernate.HibernateDatastore,144,CloseResource,Ensure that resources like this HibernateDatastore object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,147,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,150,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,150,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'singletonConnectionSources' (lines '150'-'150').
-org.grails.orm.hibernate.HibernateDatastore,150,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'singletonConnectionSources' (lines '150'-'170').
-org.grails.orm.hibernate.HibernateDatastore,153,CloseResource,Ensure that resources like this HibernateDatastore object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,198,ConstructorCallsOverridableMethod,Overridable method 'initialize' called during object construction
-org.grails.orm.hibernate.HibernateDatastore,198,ConstructorCallsOverridableMethod,Overridable method 'initialize' called during object construction
-org.grails.orm.hibernate.HibernateDatastore,198,ConstructorCallsOverridableMethod,Overridable method 'initialize' called during object construction
-org.grails.orm.hibernate.HibernateDatastore,488,CloseResource,Ensure that resources like this HibernateConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,542,CloseResource,Ensure that resources like this HibernateDatastore object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,543,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.HibernateDatastore,580,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,581,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'previousMode' (lines '581'-'585').
-org.grails.orm.hibernate.HibernateDatastore,582,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'reset' (lines '582'-'589').
-org.grails.orm.hibernate.HibernateDatastore,589,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'reset' (lines '589'-'591').
-org.grails.orm.hibernate.HibernateDatastore,632,CloseResource,Ensure that resources like this HibernateConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,641,CloseResource,Ensure that resources like this Connection object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,669,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'factory' (lines '669'-'751').
-org.grails.orm.hibernate.HibernateDatastore,669,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'factory' (lines '669'-'751').
-org.grails.orm.hibernate.HibernateDatastore,669,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'factory' (lines '669'-'751').
-org.grails.orm.hibernate.HibernateDatastore,669,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'factory' (lines '669'-'751').
-org.grails.orm.hibernate.HibernateDatastore,671,CloseResource,Ensure that resources like this HibernateConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,671,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'defaultConnectionSource' (lines '671'-'751').
-org.grails.orm.hibernate.HibernateDatastore,671,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'defaultConnectionSource' (lines '671'-'751').
-org.grails.orm.hibernate.HibernateDatastore,671,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'defaultConnectionSource' (lines '671'-'751').
-org.grails.orm.hibernate.HibernateDatastore,671,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'defaultConnectionSource' (lines '671'-'751').
-org.grails.orm.hibernate.HibernateDatastore,675,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tenantSettings' (lines '675'-'751').
-org.grails.orm.hibernate.HibernateDatastore,675,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tenantSettings' (lines '675'-'751').
-org.grails.orm.hibernate.HibernateDatastore,675,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tenantSettings' (lines '675'-'751').
-org.grails.orm.hibernate.HibernateDatastore,675,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tenantSettings' (lines '675'-'751').
-org.grails.orm.hibernate.HibernateDatastore,710,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.HibernateDatastore,734,CloseResource,Ensure that resources like this DefaultConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,736,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,739,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,742,CloseResource,Ensure that resources like this SingletonConnectionSources object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,754,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'metadata' (lines '754'-'763').
-org.grails.orm.hibernate.HibernateDatastore,755,CloseResource,Ensure that resources like this ServiceRegistry object are closed after use
-org.grails.orm.hibernate.HibernateDatastore,763,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'metadata' (lines '763'-'763').
-org.grails.orm.hibernate.HibernateMappingContextSessionFactoryBean,460,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.HibernateMappingContextSessionFactoryBean,502,EmptyIfStmt,Avoid empty if statements
-org.grails.orm.hibernate.HibernateSession,80,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'cpf' (lines '80'-'88').
-org.grails.orm.hibernate.HibernateSession,183,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'persistentEntity' (lines '183'-'200').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,50,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,85,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '85'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,85,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '85'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,85,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '85'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,85,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '85'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,91,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '91'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,91,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '91'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,91,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '91'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,91,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '91'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,94,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '94'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,94,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '94'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,94,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '94'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,94,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'getter' (lines '94'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '95'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '95'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '95'-'115').
-org.grails.orm.hibernate.access.TraitPropertyAccessStrategy,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'setter' (lines '95'-'115').
-org.grails.orm.hibernate.cfg.GrailsHibernateUtil,80,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.cfg.GrailsHibernateUtil,104,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.cfg.GrailsHibernateUtil,109,CloseResource,Ensure that resources like this SessionImplementor object are closed after use
-org.grails.orm.hibernate.cfg.GrailsHibernateUtil,116,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'actualTarget' (lines '116'-'118').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,191,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.HibernateMappingContext,193,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.HibernateMappingContext,337,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'customTypeMarshaller' (lines '337'-'340').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'368').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'368').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'368').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'368').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'368').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'370').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'370').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'370').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'370').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'resolvedGenerator' (lines '364'-'370').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'resolvedGenerator' (lines '364'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'resolvedGenerator' (lines '364'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'resolvedGenerator' (lines '364'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'resolvedGenerator' (lines '364'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,364,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'resolvedGenerator' (lines '364'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,379,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '379'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,379,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '379'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,379,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '379'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,379,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '379'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,379,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '379'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,381,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '381'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,381,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '381'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,381,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '381'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,381,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '381'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,381,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '381'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,384,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '384'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,384,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '384'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,384,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '384'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,384,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '384'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContext,384,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generator' (lines '384'-'417').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,118,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,139,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,192,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'readerFactory' (lines '192'-'192').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,192,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'readerFactory' (lines '192'-'210').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,197,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'className' (lines '197'-'197').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,197,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'className' (lines '197'-'210').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,199,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,251,UseProperClassLoader,"In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,256,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'domainBinder' (lines '256'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,256,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'domainBinder' (lines '256'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,256,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'domainBinder' (lines '256'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,256,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'domainBinder' (lines '256'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,277,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'classLoaderService' (lines '277'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,277,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'classLoaderService' (lines '277'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,277,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'classLoaderService' (lines '277'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,277,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'classLoaderService' (lines '277'-'330').
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,292,CloseResource,Ensure that resources like this BootstrapServiceRegistry object are closed after use
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,321,CloseResource,Ensure that resources like this StandardServiceRegistry object are closed after use
-org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration,324,AvoidCatchingThrowable,A catch statement should never catch throwable since it includes errors.
-org.grails.orm.hibernate.cfg.IdentityEnumType,63,AvoidFieldNameMatchingMethodName,Field sqlTypes has the same name as a method
-org.grails.orm.hibernate.cfg.IdentityEnumType,118,SuspiciousEqualsMethodName,The method name and parameter number are suspiciously close to equals(Object)
-org.grails.orm.hibernate.cfg.IdentityEnumType,119,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.cfg.MappingCacheHolder,65,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'className' (lines '65'-'73').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ClassPropertiesBinder,72,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'table' (lines '72'-'89').
-org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder,265,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'schemaName' (lines '265'-'269').
-org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder,266,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'catalogName' (lines '266'-'272').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,80,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,81,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,82,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,83,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,84,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,139,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'mappedForm' (lines '139'-'145').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,139,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'mappedForm' (lines '139'-'148').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder,139,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'mappedForm' (lines '139'-'186').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,68,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'table' (lines '68'-'86').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,69,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'persistentClass' (lines '69'-'86').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder,70,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'currentPath' (lines '70'-'86').
-org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder,73,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'identifierProp' (lines '73'-'80').
-org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder,89,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'j' (lines '89'-'151').
-org.grails.orm.hibernate.cfg.domainbinding.binder.DiscriminatorPropertyBinder,68,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'typeName' (lines '68'-'76').
-org.grails.orm.hibernate.cfg.domainbinding.binder.DiscriminatorPropertyBinder,68,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'typeName' (lines '68'-'78').
-org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder,87,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'enumType' (lines '87'-'138').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBinder,240,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'rootBinder' (lines '240'-'256').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'106').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'109').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'113').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'115').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'118').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'94').
-org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder,89,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'value' (lines '89'-'99').
-org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder,123,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'config' (lines '123'-'141').
-org.grails.orm.hibernate.cfg.domainbinding.binder.NumericColumnConstraintsBinder,36,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'scale' (lines '36'-'56').
-org.grails.orm.hibernate.cfg.domainbinding.binder.RootBinder,86,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'm' (lines '86'-'99').
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder,88,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'id' (lines '88'-'125').
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder,92,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'identifier' (lines '92'-'125').
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,80,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,81,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,82,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,83,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,84,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder,85,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIdentityGenerator,27,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,49,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,70,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,110,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,114,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,116,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,138,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,146,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,156,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,177,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,186,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,197,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,202,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsIncrementGenerator,205,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsNativeGenerator,27,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsNativeGenerator,34,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsSequenceStyleGenerator,30,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsSequenceStyleGenerator,59,ConstructorCallsOverridableMethod,Overridable method 'initialize' called during object construction
-org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsTableGenerator,30,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentProperty,131,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'userType' (lines '131'-'133').
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentProperty,131,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'userType' (lines '131'-'137').
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentProperty,138,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentProperty,283,ReturnEmptyCollectionRatherThanNull,Return an empty collection rather than null.
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity,50,ReturnEmptyArrayRatherThanNull,Return an empty array rather than null.
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity,51,ReturnEmptyCollectionRatherThanNull,Return an empty collection rather than null.
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,77,ReturnEmptyCollectionRatherThanNull,Return an empty collection rather than null.
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,79,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'result' (lines '79'-'82').
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,82,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'result' (lines '82'-'82').
-org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity,83,NullAssignment,Assigning an Object to null is a code smell.  Consider refactoring.
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'associatedClass' (lines '95'-'179').
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionWithJoinTableBinder,96,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'joinColumnMappingOptional' (lines '96'-'152').
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPass,32,NonSerializableClass,The field 'listSecondPassBinder' of serializable class 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPass' is of non-serializable type 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder'.
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder,73,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'columnName' (lines '73'-'152').
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder,106,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'referenced' (lines '106'-'152').
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPass,32,NonSerializableClass,The field 'mapSecondPassBinder' of serializable class 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPass' is of non-serializable type 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPassBinder'.
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPassBinder,96,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'typeName' (lines '96'-'98').
-org.grails.orm.hibernate.cfg.domainbinding.secondpass.SetSecondPass,39,NonSerializableClass,The field 'collectionSecondPassBinder' of serializable class 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.SetSecondPass' is of non-serializable type 'org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder'.
-org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator,60,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'generatorName' (lines '60'-'64').
-org.grails.orm.hibernate.cfg.domainbinding.util.CascadeBehavior,94,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.cfg.domainbinding.util.CreateKeyForProps,58,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'owner' (lines '58'-'75').
-org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher,49,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'columnName' (lines '49'-'87').
-org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher,51,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'association' (lines '51'-'87').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,30,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '30'-'38').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,30,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '30'-'41').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,38,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '38'-'38').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,38,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '38'-'41').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,41,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '41'-'38').
-org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator,41,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'expectedForeignKeyColumnLength' (lines '41'-'41').
-org.grails.orm.hibernate.cfg.domainbinding.util.GrailsOneToOne,44,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.cfg.domainbinding.util.LogCascadeMapping,30,LoggerIsNotStaticFinal,The Logger variable declaration does not contain the static and final modifiers
-org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,57,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entries' (lines '57'-'83').
-org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,68,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,95,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tablePrefix' (lines '95'-'101').
-org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,96,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'direction' (lines '96'-'101').
-org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder,106,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,56,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'propertyColumnName' (lines '56'-'118').
-org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,59,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'hasJoinTableMapping' (lines '59'-'118').
-org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,61,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'left' (lines '61'-'118').
-org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator,92,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'right' (lines '92'-'118').
-org.grails.orm.hibernate.cfg.domainbinding.util.UniqueNameGenerator,51,AvoidLiteralsInIfCondition,Avoid using Literals in Conditional Statements
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,60,CloseResource,Ensure that resources like this ConnectionSource object are closed after use
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,104,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'dsfallbackSettings' (lines '104'-'106').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,104,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'dsfallbackSettings' (lines '104'-'109').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,130,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'dsfallbackSettings' (lines '130'-'132').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,130,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'dsfallbackSettings' (lines '130'-'134').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,130,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dsfallbackSettings' (lines '130'-'156').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,132,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dsfallbackSettings' (lines '132'-'156').
-org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory,134,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dsfallbackSettings' (lines '134'-'156').
-org.grails.orm.hibernate.connections.HibernateConnectionSource,53,CloseResource,Ensure that resources like this SessionFactory object are closed after use
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,101,CloseResource,Ensure that resources like this SessionFactory object are closed after use
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,110,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'isDefault' (lines '110'-'277').
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,133,CloseResource,Ensure that resources like this JakartaValidatorRegistry object are closed after use
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,155,AvoidDuplicateLiterals,"The String literal ""Cannot configure Hibernate config for location: "" appears 5 times in this file; the first occurrence is on line 155"
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,205,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'file' (lines '205'-'277').
-org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory,258,AvoidCatchingThrowable,A catch statement should never catch throwable since it includes errors.
-org.grails.orm.hibernate.event.listener.HibernateEventListener,106,CloseResource,Ensure that resources like this EventSource object are closed after use
-org.grails.orm.hibernate.event.listener.HibernateEventListener,119,CloseResource,Ensure that resources like this EventSource object are closed after use
-org.grails.orm.hibernate.event.listener.HibernateEventListener,154,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'evict' (lines '154'-'158').
-org.grails.orm.hibernate.event.listener.HibernateEventListener,164,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'evict' (lines '164'-'168').
-org.grails.orm.hibernate.event.listener.HibernateEventListener,182,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'evict' (lines '182'-'186').
-org.grails.orm.hibernate.event.listener.HibernateEventListener,222,CloseResource,Ensure that resources like this AbstractHibernateDatastore object are closed after use
-org.grails.orm.hibernate.multitenancy.MultiTenantEventListener,59,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'hibernateDatastore' (lines '59'-'114').
-org.grails.orm.hibernate.multitenancy.MultiTenantEventListener,79,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tenantId' (lines '79'-'114').
-org.grails.orm.hibernate.multitenancy.MultiTenantEventListener,93,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.proxy.HibernateProxyHandler,155,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,68,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'orderParam' (lines '68'-'122').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,84,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'ignoreCase' (lines '84'-'87').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,84,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'ignoreCase' (lines '84'-'122').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,87,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'ignoreCase' (lines '87'-'122').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,138,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'maxParam' (lines '138'-'141').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,139,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'offsetParam' (lines '139'-'144').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,201,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'sortTail' (lines '201'-'225').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,214,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'propertyTargetClass' (lines '214'-'225').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,252,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'orderComparator' (lines '252'-'317').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,252,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'orderComparator' (lines '252'-'317').
-org.grails.orm.hibernate.query.GrailsHibernateQueryUtils,252,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'orderComparator' (lines '252'-'317').
-org.grails.orm.hibernate.query.HibernateHqlQuery,100,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'values' (lines '100'-'112').
-org.grails.orm.hibernate.query.HibernateHqlQuery,131,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'positionalParams' (lines '131'-'176').
-org.grails.orm.hibernate.query.HibernateHqlQuery,136,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'args' (lines '136'-'176').
-org.grails.orm.hibernate.query.HibernateHqlQuery,138,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'hibernateHqlQuery' (lines '138'-'176').
-org.grails.orm.hibernate.query.HibernateHqlQuery,143,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'clazz' (lines '143'-'176').
-org.grails.orm.hibernate.query.HibernateHqlQuery,144,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'q' (lines '144'-'146').
-org.grails.orm.hibernate.query.HibernateHqlQuery,144,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'q' (lines '144'-'148').
-org.grails.orm.hibernate.query.HibernateHqlQuery,144,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'q' (lines '144'-'150').
-org.grails.orm.hibernate.query.HibernateHqlQuery,193,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,194,AvoidDuplicateLiterals,"The String literal ""select "" appears 6 times in this file; the first occurrence is on line 194"
-org.grails.orm.hibernate.query.HibernateHqlQuery,200,AvoidDuplicateLiterals,"The String literal "" from "" appears 5 times in this file; the first occurrence is on line 200"
-org.grails.orm.hibernate.query.HibernateHqlQuery,210,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,211,AvoidDuplicateLiterals,"The String literal ""distinct "" appears 9 times in this file; the first occurrence is on line 211"
-org.grails.orm.hibernate.query.HibernateHqlQuery,213,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'selLower' (lines '213'-'266').
-org.grails.orm.hibernate.query.HibernateHqlQuery,213,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,214,AvoidDuplicateLiterals,"The String literal ""all "" appears 8 times in this file; the first occurrence is on line 214"
-org.grails.orm.hibernate.query.HibernateHqlQuery,216,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,219,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'depth' (lines '219'-'253').
-org.grails.orm.hibernate.query.HibernateHqlQuery,222,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'topLevelCommas' (lines '222'-'261').
-org.grails.orm.hibernate.query.HibernateHqlQuery,236,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'i' (lines '236'-'229').
-org.grails.orm.hibernate.query.HibernateHqlQuery,261,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'topLevelCommas' (lines '261'-'261').
-org.grails.orm.hibernate.query.HibernateHqlQuery,302,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,316,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'selectClauseOrig' (lines '316'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,317,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'selectClauseLower' (lines '317'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,336,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'hasAlias' (lines '336'-'372').
-org.grails.orm.hibernate.query.HibernateHqlQuery,337,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'alias' (lines '337'-'373').
-org.grails.orm.hibernate.query.HibernateHqlQuery,337,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'alias' (lines '337'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,338,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'aliasStart' (lines '338'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,340,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'nextWord' (lines '340'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,340,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,358,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,373,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'alias' (lines '373'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,386,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'prefix' (lines '386'-'390').
-org.grails.orm.hibernate.query.HibernateHqlQuery,386,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'prefix' (lines '386'-'397').
-org.grails.orm.hibernate.query.HibernateHqlQuery,387,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'projOrig' (lines '387'-'398').
-org.grails.orm.hibernate.query.HibernateHqlQuery,390,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'prefix' (lines '390'-'395').
-org.grails.orm.hibernate.query.HibernateHqlQuery,402,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'adjustedProjection' (lines '402'-'405').
-org.grails.orm.hibernate.query.HibernateHqlQuery,402,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'adjustedProjection' (lines '402'-'411').
-org.grails.orm.hibernate.query.HibernateHqlQuery,404,UnnecessaryCaseChange,Using equalsIgnoreCase() is cleaner than using toUpperCase/toLowerCase().equals().
-org.grails.orm.hibernate.query.HibernateHqlQuery,404,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateHqlQuery,419,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'tail' (lines '419'-'427').
-org.grails.orm.hibernate.query.HibernateHqlQuery,430,UseLocaleWithCaseConversions,"When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
-org.grails.orm.hibernate.query.HibernateQuery,334,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'subCriteria' (lines '334'-'341').
-org.grails.orm.hibernate.query.HibernateQuery,334,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'subCriteria' (lines '334'-'344').
-org.grails.orm.hibernate.query.HibernateQuery,628,CloneMethodReturnTypeMustMatchClassName,The return type of the clone() method must be the class name when implements Cloneable
-org.grails.orm.hibernate.query.HibernateQuery,628,CloneThrowsCloneNotSupportedException,clone() method should throw CloneNotSupportedException
-org.grails.orm.hibernate.query.JpaCriteriaQueryCreator,131,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'jpaOrders' (lines '131'-'151').
-org.grails.orm.hibernate.query.JpaFromProvider,62,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'fromsByName' (lines '62'-'112').
-org.grails.orm.hibernate.query.JpaFromProvider,150,AvoidLiteralsInIfCondition,Avoid using Literals in Conditional Statements
-org.grails.orm.hibernate.query.JpaFromProvider,162,ProperCloneImplementation,Object clone() should be implemented with super.clone()
-org.grails.orm.hibernate.query.JpaFromProvider,162,CloneMethodReturnTypeMustMatchClassName,The return type of the clone() method must be the class name when implements Cloneable
-org.grails.orm.hibernate.query.JpaFromProvider,162,CloneThrowsCloneNotSupportedException,clone() method should throw CloneNotSupportedException
-org.grails.orm.hibernate.query.PagedResultList,31,MissingSerialVersionUID,Classes implementing Serializable should set a serialVersionUID
-org.grails.orm.hibernate.query.PredicateGenerator,114,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'predicates' (lines '114'-'128').
-org.grails.orm.hibernate.query.PredicateGenerator,121,AvoidLiteralsInIfCondition,Avoid using Literals in Conditional Statements
-org.grails.orm.hibernate.query.PredicateGenerator,139,AvoidDuplicateLiterals,"The String literal ""root"" appears 4 times in this file; the first occurrence is on line 139"
-org.grails.orm.hibernate.query.PredicateGenerator,151,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'fullyQualifiedPath' (lines '151'-'196').
-org.grails.orm.hibernate.query.PredicateGenerator,212,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'from2' (lines '212'-'232').
-org.grails.orm.hibernate.query.PredicateGenerator,213,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'newMap2' (lines '213'-'232').
-org.grails.orm.hibernate.query.PredicateGenerator,280,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'predicates' (lines '280'-'313').
-org.grails.orm.hibernate.query.PredicateGenerator,282,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'path' (lines '282'-'313').
-org.grails.orm.hibernate.query.PredicateGenerator,320,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'path' (lines '320'-'329').
-org.grails.orm.hibernate.query.PredicateGenerator,321,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'otherPath' (lines '321'-'329').
-org.grails.orm.hibernate.query.PredicateGenerator,333,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'path' (lines '333'-'339').
-org.grails.orm.hibernate.support.ClosureEventListener,142,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.support.ClosureEventListener,144,AvoidAccessibilityAlteration,"You should not modify visibility of constructors, methods or fields using setAccessible()"
-org.grails.orm.hibernate.support.ClosureEventListener,145,EmptyCatchBlock,Avoid empty catch blocks
-org.grails.orm.hibernate.support.ClosureEventListener,187,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '187'-'201').
-org.grails.orm.hibernate.support.ClosureEventListener,187,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '187'-'201').
-org.grails.orm.hibernate.support.ClosureEventListener,214,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '214'-'228').
-org.grails.orm.hibernate.support.ClosureEventListener,214,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '214'-'228').
-org.grails.orm.hibernate.support.ClosureEventListener,231,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '231'-'245').
-org.grails.orm.hibernate.support.ClosureEventListener,231,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entity' (lines '231'-'245').
-org.grails.orm.hibernate.support.ClosureEventListener,311,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'evict' (lines '311'-'314').
-org.grails.orm.hibernate.support.ClosureEventListener,314,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'evict' (lines '314'-'323').
-org.grails.orm.hibernate.support.ClosureEventListener,340,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'reflector' (lines '340'-'366').
-org.grails.orm.hibernate.support.ClosureEventListener,342,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entityMetamodel' (lines '342'-'366').
-org.grails.orm.hibernate.support.ClosureEventListener,359,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.support.ClosureEventListener,381,CompareObjectsWithEquals,Use equals() to compare object references.
-org.grails.orm.hibernate.support.ClosureEventListener,385,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'updateState' (lines '385'-'382').
-org.grails.orm.hibernate.support.ClosureEventListener,385,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'updateState' (lines '385'-'385').
-org.grails.orm.hibernate.support.ClosureEventListener,385,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'updateState' (lines '385'-'395').
-org.grails.orm.hibernate.support.ClosureEventListener,398,CloseResource,Ensure that resources like this Session object are closed after use
-org.grails.orm.hibernate.support.ClosureEventListener,399,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'current' (lines '399'-'406').
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,72,NonSerializableClass,The field 'persistEventListener' of serializable class 'org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor' is of non-serializable type 'org.hibernate.event.internal.DefaultPersistEventListener'.
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,74,NonSerializableClass,The field 'mergeEventListener' of serializable class 'org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor' is of non-serializable type 'org.hibernate.event.internal.DefaultMergeEventListener'.
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,234,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'entityAccess' (lines '234'-'236').
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,305,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'entityMetamodel' (lines '305'-'312').
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,328,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'entityAccess' (lines '328'-'330').
-org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor,397,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dirtyCheckable' (lines '397'-'415').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,94,CloseResource,Ensure that resources like this Connection object are closed after use
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,94,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'connection' (lines '94'-'100').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,94,DataflowAnomalyAnalysis,Found 'DD'-anomaly for variable 'connection' (lines '94'-'100').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,96,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dbName' (lines '96'-'139').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,96,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dbName' (lines '96'-'139').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,103,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dialectFactory' (lines '103'-'139').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,103,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'dialectFactory' (lines '103'-'139').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,104,CloseResource,Ensure that resources like this Connection object are closed after use
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,105,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'infoSource' (lines '105'-'139').
-org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean,105,DataflowAnomalyAnalysis,Found 'DU'-anomaly for variable 'infoSource' (lines '105'-'139').
-org.grails.orm.hibernate.transaction.HibernateJtaTransactionManagerAdapter,217,CompareObjectsWithEquals,Use equals() to compare object references.
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
index b250a2c714..80a4d021d1 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
@@ -140,10 +140,6 @@ class Mapping extends Entity<PropertyConfig> {
     String comment
 
 
-    boolean isTablePerHierarchy() {
-        return tablePerHierarchy
-    }
-
     boolean isJoinedSubclass() {
         return !tablePerHierarchy && !tablePerConcreteClass
     }
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
index 4a5a055603..b68a726b51 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ColumnBinder.java
@@ -146,7 +146,8 @@ public class ColumnBinder {
 
     var owner = property.getHibernateOwner();
     if (!owner.isRoot()) {
-      if (owner.isTablePerHierarchy()) {
+      Mapping mapping = owner.getMappedForm();
+      if (mapping != null && mapping.getTablePerHierarchy()) {
         if (LOG.isDebugEnabled())
           LOG.debug(
               "[GrailsDomainBinder] Sub class property ["
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/IndexBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/IndexBinder.java
index 97d4a0abbf..54e34f31aa 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/IndexBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/IndexBinder.java
@@ -36,7 +36,14 @@ public class IndexBinder {
               if (indexObj instanceof Boolean b) {
                 return b ? of(format("%s_%s_idx", table.getName(), columnName)) : empty();
               }
-              return of(indexObj.toString());
+              String indexStr = indexObj.toString();
+              if ("true".equalsIgnoreCase(indexStr)) {
+                return of(format("%s_%s_idx", table.getName(), columnName));
+              }
+              if ("false".equalsIgnoreCase(indexStr)) {
+                return empty();
+              }
+              return of(indexStr);
             })
         .map(def -> def.split(","))
         .ifPresent(
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
index 835694a45b..9c4840a514 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
@@ -78,10 +78,8 @@ public class RootBinder {
       discriminatorPropertyBinder.bindDiscriminatorProperty(root);
     }
 
-    Mapping m = entity.getMappedForm();
-
     // bind the sub classes
-    children.forEach(sub -> subClassBinder.bindSubClass(sub, root, mappings, m));
+    children.forEach(sub -> subClassBinder.bindSubClass(sub, root, mappings));
 
     multiTenantFilterBinder.bind(entity, root);
 
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
index f73424b2c5..1da4593f1c 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
@@ -56,19 +56,17 @@ public class SubClassBinder {
    * @param sub The sub domain class instance
    * @param parent The parent persistent class instance
    * @param mappings The mappings instance
-   * @param m The mapping config
    */
   public void bindSubClass(
       @Nonnull GrailsHibernatePersistentEntity sub,
       PersistentClass parent,
-      @Nonnull InFlightMetadataCollector mappings,
-      Mapping m) {
+      @Nonnull InFlightMetadataCollector mappings) {
     mappingCacheHolder.cacheMapping(sub);
-    Subclass subClass = subclassMappingBinder.createSubclassMapping(sub, parent, mappings, m);
+    Subclass subClass = subclassMappingBinder.createSubclassMapping(sub, parent, mappings);
     parent.addSubclass(subClass);
     mappings.addEntityBinding(subClass);
     bindMultiTenantFilter(sub, subClass);
-    sub.getChildEntities(dataSourceName).forEach(sub1 -> bindSubClass(sub1, subClass, mappings, m));
+    sub.getChildEntities(dataSourceName).forEach(sub1 -> bindSubClass(sub1, subClass, mappings));
   }
 
   private void bindMultiTenantFilter(GrailsHibernatePersistentEntity sub, Subclass subClass) {
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
index 08dc1fa15d..755641307a 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
@@ -55,24 +55,26 @@ public class SubclassMappingBinder {
   public @NonNull Subclass createSubclassMapping(
       @NonNull GrailsHibernatePersistentEntity subEntity,
       PersistentClass parent,
-      @NonNull InFlightMetadataCollector mappings,
-      Mapping m) {
+      @NonNull InFlightMetadataCollector mappings) {
     Subclass subClass;
     subEntity.configureDerivedProperties();
-    if (m.isJoinedSubclass()) {
+    Mapping m = subEntity.getMappedForm();
+    if (subEntity.isJoinedSubclass()) {
       var joined = new JoinedSubclass(parent, this.metadataBuildingContext);
       joinedSubClassBinder.bindJoinedSubClass(subEntity, joined, mappings);
       subClass = joined;
-    } else if (m.isUnionSubclass()) {
+    } else if (subEntity.isUnionSubclass()) {
       var union = new UnionSubclass(parent, this.metadataBuildingContext);
       unionSubclassBinder.bindUnionSubclass(subEntity, union, mappings);
       subClass = union;
     } else {
+
       var singleTableSubclass = new SingleTableSubclass(parent, this.metadataBuildingContext);
 
       singleTableSubclassBinder.bindSubClass(subEntity, singleTableSubclass, mappings);
       subClass = singleTableSubclass;
     }
+
     subClass.setBatchSize(Optional.ofNullable(m.getBatchSize()).orElse(-1));
     subClass.setDynamicUpdate(m.getDynamicUpdate());
     subClass.setDynamicInsert(m.getDynamicInsert());
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
index 3911799126..20ac8e2c7b 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
@@ -49,22 +49,31 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
     return (GrailsHibernatePersistentEntity) getRootEntity();
   }
 
+  default GrailsHibernatePersistentEntity getStrategyOwner() {
+    List<HibernatePersistentProperty> props = getHibernatePersistentProperties();
+    return (props != null && !props.isEmpty()) ? props.get(0).getHibernateOwner() : this;
+  }
+
+  default Mapping getStrategyMapping() {
+    return getStrategyOwner().getMappedForm();
+  }
+
   default Mapping getRootMapping() {
     return getHibernateRootEntity().getMappedForm();
   }
 
   default boolean isTablePerHierarchy() {
-    Mapping mapping = getMappedForm();
+    Mapping mapping = getStrategyMapping();
     return mapping == null || mapping.isTablePerHierarchy();
   }
 
   default boolean isJoinedSubclass() {
-    Mapping mapping = getMappedForm();
+    Mapping mapping = getStrategyMapping();
     return mapping != null && mapping.isJoinedSubclass();
   }
 
   default boolean isUnionSubclass() {
-    Mapping mapping = getMappedForm();
+    Mapping mapping = getStrategyMapping();
     return mapping != null && mapping.isUnionSubclass();
   }
 
@@ -73,7 +82,7 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
   }
 
   default boolean isTablePerHierarchySubclass() {
-    return !this.isRoot() && getHibernateRootEntity().isTablePerHierarchy();
+    return !this.isRoot() && isTablePerHierarchy();
   }
 
   default Set<String> buildDiscriminatorSet() {
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
index 144cdcf532..9d99c2db1d 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
@@ -56,7 +56,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
         then:
         1 * rootPersistentClassCommonValuesBinder.bindRootPersistentClassCommonValues(entity, [], mappings) >> rootClass
         0 * discriminatorPropertyBinder.bindDiscriminatorProperty(_)
-        0 * subClassBinder.bindSubClass(_, _, _, _)
+        0 * subClassBinder.bindSubClass(_, _, _)
         1 * multiTenantFilterBinder.bind(entity, rootClass)
         mappings.getEntityBinding("Parent") == rootClass
     }
@@ -83,7 +83,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
         then:
         1 * rootPersistentClassCommonValuesBinder.bindRootPersistentClassCommonValues(entity, [childEntity], mappings) >> rootClass
         1 * discriminatorPropertyBinder.bindDiscriminatorProperty(rootClass)
-        1 * subClassBinder.bindSubClass(childEntity, rootClass, mappings, mapping)
+        1 * subClassBinder.bindSubClass(childEntity, rootClass, mappings)
         1 * multiTenantFilterBinder.bind(entity, rootClass)
         mappings.getEntityBinding("Parent") == rootClass
     }
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
index 7d5378055f..eb7ba303dd 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
@@ -51,10 +51,10 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
         subClass.setJpaEntityName("Child")
 
         when:
-        binder.bindSubClass(subEntity, rootClass, mappings, mapping)
+        binder.bindSubClass(subEntity, rootClass, mappings)
 
         then:
-        1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings, mapping) >> subClass
+        1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings) >> subClass
         1 * multiTenantFilterBinder.bind(subEntity, subClass)
         rootClass.getSubclasses().contains(subClass)
         mappings.getEntityBinding(subClass.getEntityName()) == subClass
@@ -83,11 +83,11 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
         grandChildSubClass.setJpaEntityName("GrandChild")
 
         when:
-        binder.bindSubClass(subEntity, rootClass, mappings, mapping)
+        binder.bindSubClass(subEntity, rootClass, mappings)
 
         then:
-        1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings, mapping) >> subClass
-        1 * subclassMappingBinder.createSubclassMapping(grandChildEntity, subClass, mappings, mapping) >> grandChildSubClass
+        1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings) >> subClass
+        1 * subclassMappingBinder.createSubclassMapping(grandChildEntity, subClass, mappings) >> grandChildSubClass
         2 * multiTenantFilterBinder.bind(_, _)
         rootClass.getSubclasses().contains(subClass)
         subClass.getSubclasses().contains(grandChildSubClass)
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
index 3936ae8e3e..77492c8ad7 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
@@ -10,6 +10,7 @@ import org.hibernate.mapping.RootClass
 import org.hibernate.mapping.SingleTableSubclass
 import org.hibernate.mapping.Subclass
 import org.hibernate.mapping.UnionSubclass
+import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
 import spock.lang.Shared
 
 class SubclassMappingBinderSpec extends HibernateGormDatastoreSpec {
@@ -22,7 +23,6 @@ class SubclassMappingBinderSpec extends HibernateGormDatastoreSpec {
     ClassPropertiesBinder classPropertiesBinder
 
     void setup() {
-        manager.addAllDomainClasses([SMBSDefaultSuperEntity, SMBSDefaultSubEntity])
         def gdb = getGrailsDomainBinder()
         metadataBuildingContext = gdb.getMetadataBuildingContext()
         joinedSubClassBinder = Mock(JoinedSubClassBinder)
@@ -41,71 +41,101 @@ class SubclassMappingBinderSpec extends HibernateGormDatastoreSpec {
 
     def "test createSubclassMapping for single table inheritance"() {
         given:
-        def subEntity = createPersistentEntity(SMBSDefaultSubEntity) as org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        createPersistentEntity(SMBSSingleSuper)
+        def subEntity = createPersistentEntity(SMBSSingleSub)
         def rootClass = new RootClass(metadataBuildingContext)
-        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        rootClass.setEntityName(SMBSSingleSuper.name)
+        rootClass.setJpaEntityName(SMBSSingleSuper.name)
         def mappings = getCollector()
-        def mapping = new Mapping()
-        mapping.setTablePerHierarchy(true)
 
         when:
-        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings, mapping)
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings)
 
         then:
+        subEntity != null
         1 * singleTableSubclassBinder.bindSubClass(subEntity, _ as SingleTableSubclass, mappings)
         1 * classPropertiesBinder.bindClassProperties(subEntity, _ as Subclass, mappings)
         subClass instanceof SingleTableSubclass
-        subClass.getEntityName() == SMBSDefaultSubEntity.name
+        subClass.getEntityName() == SMBSSingleSub.name
     }
 
     def "test createSubclassMapping for joined table inheritance"() {
         given:
-        def subEntity = getPersistentEntity(SMBSDefaultSubEntity) as org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        createPersistentEntity(SMBSJoinedSuper)
+        def subEntity = createPersistentEntity(SMBSJoinedSub)
         def rootClass = new RootClass(metadataBuildingContext)
-        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        rootClass.setEntityName(SMBSJoinedSuper.name)
+        rootClass.setJpaEntityName(SMBSJoinedSuper.name)
         def mappings = getCollector()
-        def mapping = new Mapping()
-        mapping.@tablePerHierarchy = false
-        mapping.@tablePerConcreteClass = false
 
         when:
-        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings, mapping)
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings)
 
         then:
+        subEntity != null
         1 * joinedSubClassBinder.bindJoinedSubClass(subEntity, _ as JoinedSubclass, mappings)
         1 * classPropertiesBinder.bindClassProperties(subEntity, _ as Subclass, mappings)
         subClass instanceof JoinedSubclass
-        subClass.getEntityName() == SMBSDefaultSubEntity.name
+        subClass.getEntityName() == SMBSJoinedSub.name
     }
 
     def "test createSubclassMapping for table per concrete class inheritance"() {
         given:
-        def subEntity = getPersistentEntity(SMBSDefaultSubEntity) as org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        createPersistentEntity(SMBSUnionSuper)
+        def subEntity = createPersistentEntity(SMBSUnionSub)
         def rootClass = new RootClass(metadataBuildingContext)
-        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        rootClass.setEntityName(SMBSUnionSuper.name)
+        rootClass.setJpaEntityName(SMBSUnionSuper.name)
         def mappings = getCollector()
-        def mapping = new Mapping()
-        mapping.@tablePerHierarchy = false
-        mapping.@tablePerConcreteClass = true
 
         when:
-        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings, mapping)
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, mappings)
 
         then:
+        subEntity != null
         1 * unionSubclassBinder.bindUnionSubclass(subEntity, _ as UnionSubclass, mappings)
         1 * classPropertiesBinder.bindClassProperties(subEntity, _ as Subclass, mappings)
         subClass instanceof UnionSubclass
-        subClass.getEntityName() == SMBSDefaultSubEntity.name
+        subClass.getEntityName() == SMBSUnionSub.name
     }
 }
 
 @Entity
-class SMBSDefaultSuperEntity {
+class SMBSSingleSuper {
     Long id
     String name
 }
 
 @Entity
-class SMBSDefaultSubEntity extends SMBSDefaultSuperEntity {
+class SMBSSingleSub extends SMBSSingleSuper {
+    String subName
+}
+
+@Entity
+class SMBSJoinedSuper {
+    Long id
+    String name
+    static mapping = {
+        tablePerHierarchy false
+    }
+}
+
+@Entity
+class SMBSJoinedSub extends SMBSJoinedSuper {
+    String subName
+}
+
+@Entity
+class SMBSUnionSuper {
+    Long id
+    String name
+    static mapping = {
+        tablePerHierarchy false
+        tablePerConcreteClass true
+    }
+}
+
+@Entity
+class SMBSUnionSub extends SMBSUnionSuper {
     String subName
 }