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 2d842d8a5e67a93435555a79478125b0aa4d328b
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Feb 14 11:20:22 2026 -0600

    Refactor type resolution from SimpleValueBinder to 
GrailsHibernatePersistentProperty.
    
    - GrailsHibernatePersistentProperty: Added getTypeName(SimpleValue) and 
getTypeParameters(SimpleValue) default methods to encapsulate type resolution 
logic.
    - SimpleValueBinder: Simplified bindSimpleValue to use the new property 
methods.
    - GrailsHibernatePersistentPropertySpec: Added tests for the new type 
resolution methods.
    - SimpleValueBinderSpec: Updated mock expectations to align with the new 
logic.
---
 .../cfg/GrailsHibernatePersistentProperty.java     | 47 ++++++++++++++++++++--
 .../domainbinding/binder/SimpleValueBinder.java    | 18 +--------
 .../GrailsHibernatePersistentPropertySpec.groovy   | 44 ++++++++++++++++++++
 .../cfg/domainbinding/SimpleValueBinderSpec.groovy | 12 ++++++
 4 files changed, 101 insertions(+), 20 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentProperty.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentProperty.java
index ba33ea79b1..b1bb48c7eb 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentProperty.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentProperty.java
@@ -8,9 +8,11 @@ import java.util.List;
 import java.util.Optional;
 
 import org.hibernate.MappingException;
+import org.hibernate.mapping.DependantValue;
 import org.hibernate.mapping.IndexedCollection;
 import org.hibernate.mapping.ManyToOne;
 import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
 import org.hibernate.usertype.UserCollectionType;
 
 /**
@@ -153,18 +155,55 @@ public interface GrailsHibernatePersistentProperty 
extends PersistentProperty<Pr
                         .orElseGet(this::getMappedColumnName));
     }
 
-    default boolean isBidirectionalManyToOneWithListMapping( Property prop) {
-       if(this instanceof Association<?> association) {
-
+    default boolean isBidirectionalManyToOneWithListMapping(Property prop) {
+        if (this instanceof Association<?> association) {
             return association.isBidirectional()
                     && association.getInverseSide() != null
                     && List.class.isAssignableFrom(this.getType())
                     && prop != null
                     && prop.getValue() instanceof ManyToOne;
-
         }
         return false;
     }
 
+    /**
+     * @param simpleValue The Hibernate simple value
+     * @return The type name
+     */
+    default String getTypeName(SimpleValue simpleValue) {
+        GrailsHibernatePersistentProperty actualTypeProperty = 
getTypeProperty(simpleValue);
+        String typeName = actualTypeProperty.getTypeName();
+        if (typeName == null) {
+            if (!(actualTypeProperty instanceof Association)) {
+                Class<?> type = actualTypeProperty.getType();
+                if (type != null) {
+                    return type.getName();
+                }
+            }
+            return null;
+        }
+        return typeName;
+    }
 
+    /**
+     * @param simpleValue The Hibernate simple value
+     * @return The type parameters
+     */
+    default java.util.Properties getTypeParameters(SimpleValue simpleValue) {
+        if (getTypeName(simpleValue) != null) {
+            return 
Optional.ofNullable(getTypeProperty(simpleValue).getMappedForm()).map(PropertyConfig::getTypeParams).orElse(null);
+        }
+        return null;
+    }
+
+    /**
+     * @param simpleValue The Hibernate simple value
+     * @return The property that defines the type
+     */
+    default GrailsHibernatePersistentProperty getTypeProperty(SimpleValue 
simpleValue) {
+        if (simpleValue instanceof DependantValue) {
+            return 
Optional.ofNullable(getHibernateOwner().getIdentity()).orElse(this);
+        }
+        return this;
+    }
 }
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
index bc03a8c84a..d9b365e587 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SimpleValueBinder.java
@@ -62,23 +62,9 @@ public class SimpleValueBinder {
             SimpleValue simpleValue,
             String path) {
 
-        GrailsHibernatePersistentProperty actualTypeProperty = property;
-        if (simpleValue instanceof DependantValue) {
-            actualTypeProperty = 
Optional.ofNullable(property.getHibernateOwner().getIdentity()).orElse(property);
-        }
         PropertyConfig propertyConfig = property.getMappedForm();
-        final String typeName = actualTypeProperty.getTypeName();
-        if (typeName == null) {
-            if (!(actualTypeProperty instanceof 
org.grails.datastore.mapping.model.types.Association)) {
-                Class<?> type = actualTypeProperty.getType();
-                if (type != null) {
-                    simpleValue.setTypeName(type.getName());
-                }
-            }
-        } else {
-            simpleValue.setTypeName(typeName);
-            simpleValue.setTypeParameters(propertyConfig.getTypeParams());
-        }
+        simpleValue.setTypeName(property.getTypeName(simpleValue));
+        simpleValue.setTypeParameters(property.getTypeParameters(simpleValue));
 
         String generator = propertyConfig.getGenerator();
         if (generator != null && simpleValue instanceof BasicValue basicValue) 
{
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentPropertySpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentPropertySpec.groovy
index 10c5e0b5e7..f8f4160070 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentPropertySpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentPropertySpec.groovy
@@ -154,6 +154,50 @@ class GrailsHibernatePersistentPropertySpec extends 
HibernateGormDatastoreSpec {
         mapProp.getMapElementName(namingStrategy) == "tags_elt"
     }
 
+    void "test getTypeName(SimpleValue) and getTypeParameters(SimpleValue)"() {
+        given:
+        def domainBinder = getGrailsDomainBinder()
+        def metadataBuildingContext = domainBinder.getMetadataBuildingContext()
+        def table = 
metadataBuildingContext.getMetadataCollector().addTable(null, null, "TEST", 
null, false, metadataBuildingContext)
+        PersistentEntity entity = 
createPersistentEntity(TestEntityWithTypeName)
+        GrailsHibernatePersistentProperty property = 
(GrailsHibernatePersistentProperty) entity.getPropertyByName("name")
+        
+        def sv = new org.hibernate.mapping.BasicValue(metadataBuildingContext, 
table)
+        
+        expect:
+        property.getTypeName(sv) == "string"
+        property.getTypeParameters(sv) == null // No type params in 
TestEntityWithTypeName
+    }
+
+    void "test getTypeName(SimpleValue) with fallback"() {
+        given:
+        def domainBinder = getGrailsDomainBinder()
+        def metadataBuildingContext = domainBinder.getMetadataBuildingContext()
+        def table = 
metadataBuildingContext.getMetadataCollector().addTable(null, null, "TEST2", 
null, false, metadataBuildingContext)
+        PersistentEntity entity = createPersistentEntity(TestEntityWithEnum)
+        GrailsHibernatePersistentProperty property = 
(GrailsHibernatePersistentProperty) entity.getPropertyByName("name")
+        
+        def sv = new org.hibernate.mapping.BasicValue(metadataBuildingContext, 
table)
+        
+        expect:
+        property.getTypeName(sv) == String.name
+    }
+
+    void "test getTypeName(SimpleValue) for DependantValue"() {
+        given:
+        def domainBinder = getGrailsDomainBinder()
+        def metadataBuildingContext = domainBinder.getMetadataBuildingContext()
+        def table = 
metadataBuildingContext.getMetadataCollector().addTable(null, null, "TEST3", 
null, false, metadataBuildingContext)
+        PersistentEntity entity = createPersistentEntity(BMTOWLMAuthor)
+        GrailsHibernatePersistentProperty property = 
(GrailsHibernatePersistentProperty) entity.getPropertyByName("books")
+        
+        // DependantValue usually represents a foreign key, it should use the 
identity type of the owner
+        def dv = new 
org.hibernate.mapping.DependantValue(metadataBuildingContext, table, new 
org.hibernate.mapping.BasicValue(metadataBuildingContext, table))
+        
+        expect:
+        property.getTypeName(dv) == Long.name // Author's ID is Long
+    }
+
     void "test validateAssociation throws exception for user type"() {
         given:
         PersistentEntity entity = 
createPersistentEntity(TestEntityWithAssociations)
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy
index d5d6ceb1ed..4399d9087b 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/SimpleValueBinderSpec.groovy
@@ -59,6 +59,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(prop, null, sv, "p")
 
         then:
+        1 * prop.getTypeName(sv) >> "custom.Type"
+        1 * prop.getTypeParameters(sv) >> props
         1 * sv.setTypeName("custom.Type")
         1 * sv.setTypeParameters({ it.getProperty('p1') == 'v1' })
         1 * columnBinder.bindColumn(prop, null, _, null, 'p', null) >> { args 
->
@@ -93,6 +95,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(prop, null, sv, null)
 
         then:
+        1 * prop.getTypeName(sv) >> Integer.name
+        1 * prop.getTypeParameters(sv) >> null
         1 * sv.setTypeName(Integer.name)
         1 * columnBinder.bindColumn(prop, null, _, null, null, null) >> { args 
->
             def column = args[2] as Column
@@ -127,6 +131,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(prop, null, sv, null)
 
         then:
+        1 * prop.getTypeName(sv) >> 'X'
+        1 * prop.getTypeParameters(sv) >> null
         1 * sv.addFormula({ it.getFormula() == 'x+y' })
         0 * columnBinder.bindColumn(_, _, _, _, _, _)
 
@@ -134,6 +140,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(tenantProp, null, sv2, null)
 
         then:
+        1 * tenantProp.getTypeName(sv2) >> 'X'
+        1 * tenantProp.getTypeParameters(sv2) >> null
         0 * sv2.addFormula(_)
         1 * columnBinder.bindColumn(_, _, _, _, _, _) >> { args ->
             def column = args[2] as Column
@@ -165,6 +173,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(prop, null, sv, null)
 
         then:
+        1 * prop.getTypeName(sv) >> 'Y'
+        1 * prop.getTypeParameters(sv) >> null
         1 * columnBinder.bindColumn(prop, null, _, null, null, null) >> { args 
->
             args[2].setName("testColumn")
         }
@@ -197,6 +207,8 @@ class SimpleValueBinderSpec extends Specification {
         binder.bindSimpleValue(prop, parent, sv, 'path')
 
         then:
+        1 * prop.getTypeName(sv) >> 'Z'
+        1 * prop.getTypeParameters(sv) >> null
         1 * columnConfigToColumnBinder.bindColumnConfigToColumn(_, cc1, pc) >> 
{ args ->
             def column = args[0] as Column
             column.setName("testColumn")

Reply via email to