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 36d28d116893a95f9a9d2a49284f1145786d08fd
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Mon Feb 23 19:39:53 2026 -0600

    Last CompileDynamic
---
 grails-data-hibernate7/COMPILE-STATIC-AUDIT.md     | 11 +-------
 .../orm/hibernate/HibernateGormInstanceApi.groovy  | 31 ++++++++++++----------
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md 
b/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
index 5d8ecd1bc8..51b4cdfb4f 100644
--- a/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
+++ b/grails-data-hibernate7/COMPILE-STATIC-AUDIT.md
@@ -45,7 +45,7 @@ Legend:
 | `HibernateGormEnhancer.groovy` | ✅ Done | |
 | `HibernateGormValidationApi.groovy` | ✅ Done | |
 | `AbstractHibernateGormValidationApi.groovy` | ✅ Done | |
-| `HibernateGormInstanceApi.groovy` | ⚠️ Partial | 
`isDirty`/`findDirty`/`getDirtyPropertyNames` correctly typed. `nextId()` 
removed (dead code — no callers). Three remaining `@CompileDynamic` methods: 
`runDeferredBinding` (nullable dynamic dispatch on `DEFERRED_BINDING`), 
`setErrorsOnInstance` (dynamic property write 
`target."$GormProperties.ERRORS"`), `incrementVersion` (dynamic read/write of 
`VERSION` property). |
+| `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
@@ -120,12 +120,6 @@ Legend:
 
 ## Detailed Analysis of Remaining Partial Files
 
-### `cfg/Mapping.groovy`
-
-`methodMissing` is required for the GORM mapping DSL — domain property names 
(`firstName`, `lastName`, etc.) are user-defined and unknown to `Mapping` at 
compile time. The method itself must remain, but the `@CompileDynamic` 
annotation on its body has been removed. The only dynamic construct 
(`args[-1]`) was replaced with `((Object[])args)[args.length - 1]`.
-
----
-
 ### `liquibase/GroovyChangeLogParser.groovy`
 
 | Method | Reason dynamic | Can be fixed? |
@@ -139,9 +133,6 @@ Legend:
 
 | Action | File | Effort |
 |--------|------|--------|
-| Fix `runDeferredBinding` nullable dynamic dispatch | 
`HibernateGormInstanceApi.groovy:195` | Low |
-| Fix `setErrorsOnInstance` dynamic property write | 
`HibernateGormInstanceApi.groovy:394` | Low — use `GormValidateable` cast |
-| Fix `incrementVersion` dynamic read/write of VERSION | 
`HibernateGormInstanceApi.groovy:412` | Low — use 
`GroovyObject.getProperty`/`setProperty` with cast |
 | 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/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormInstanceApi.groovy
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormInstanceApi.groovy
index acef5522cf..5bbc0cdeb5 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormInstanceApi.groovy
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormInstanceApi.groovy
@@ -24,7 +24,6 @@ import org.hibernate.generator.Assigned
 import org.hibernate.generator.Generator
 
 import grails.gorm.validation.CascadingValidator
-import groovy.transform.CompileDynamic
 import groovy.transform.CompileStatic
 import jakarta.persistence.FlushModeType
 import org.grails.datastore.gorm.GormInstanceApi
@@ -174,9 +173,12 @@ class HibernateGormInstanceApi<D> extends 
GormInstanceApi<D> {
     }
 
 
-    @CompileDynamic
     private void runDeferredBinding() {
-        DEFERRED_BINDING?.runActions()
+        if (DEFERRED_BINDING != null) {
+            // DeferredBindingActions is from grails-data-binding (optional 
dep); invoked via reflection
+            // because it belongs to the migration plugin, which runs once per 
deployment and need not be on the compile classpath
+            DEFERRED_BINDING.getMethod('runActions').invoke(null)
+        }
     }
 
     @Override
@@ -373,13 +375,11 @@ class HibernateGormInstanceApi<D> extends 
GormInstanceApi<D> {
         return null
     }
 
-    @CompileDynamic
     protected void setErrorsOnInstance(Object target, Errors errors) {
-        if(target instanceof GormValidateable) {
-            ((GormValidateable)target).setErrors(errors)
-        }
-        else {
-            target."$GormProperties.ERRORS" = errors
+        if (target instanceof GormValidateable) {
+            ((GormValidateable) target).setErrors(errors)
+        } else {
+            ((GroovyObject) target).setProperty(GormProperties.ERRORS, errors)
         }
     }
 
@@ -391,12 +391,15 @@ class HibernateGormInstanceApi<D> extends 
GormInstanceApi<D> {
         insertActiveThreadLocal.remove();
     }
 
-    @CompileDynamic
     protected void incrementVersion(Object target) {
-        if (target.hasProperty(GormProperties.VERSION)) {
-            Object version = target."${GormProperties.VERSION}"
-            if (version instanceof Long) {
-                target."${GormProperties.VERSION}" = ++((Long)version)
+        if (target instanceof GroovyObject) {
+            GroovyObject groovyTarget = (GroovyObject) target
+            MetaProperty versionProp = 
groovyTarget.metaClass.hasProperty(groovyTarget, GormProperties.VERSION)
+            if (versionProp != null) {
+                Object version = 
groovyTarget.getProperty(GormProperties.VERSION)
+                if (version instanceof Long) {
+                    groovyTarget.setProperty(GormProperties.VERSION, ++((Long) 
version))
+                }
             }
         }
     }

Reply via email to