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 b98c7509c5dae7a4953488f0853275a4f52efef1
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Thu Feb 5 20:21:06 2026 -0600

    CollectionBinder
---
 .../cfg/domainbinding/GrailsPropertyBinder.java    | 47 ++++++++++++++++---
 .../domainbinding/GrailsPropertyBinderSpec.groovy  | 52 ++++++++++++++++++++++
 2 files changed, 92 insertions(+), 7 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinder.java
index eed6a7a709..e1503724b1 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinder.java
@@ -38,6 +38,10 @@ public class GrailsPropertyBinder {
     private final ComponentPropertyBinder componentPropertyBinder;
     private final CollectionBinder collectionBinder;
     private final PropertyFromValueCreator propertyFromValueCreator;
+    private final SimpleValueBinder simpleValueBinder;
+    private final ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher;
+    private final OneToOneBinder oneToOneBinder;
+    private final ManyToOneBinder manyToOneBinder;
 
     public GrailsPropertyBinder(
             MetadataBuildingContext metadataBuildingContext,
@@ -47,6 +51,31 @@ public class GrailsPropertyBinder {
             ComponentPropertyBinder componentPropertyBinder,
             CollectionBinder collectionBinder,
             PropertyFromValueCreator propertyFromValueCreator) {
+        this(metadataBuildingContext,
+                namingStrategy,
+                collectionHolder,
+                enumTypeBinder,
+                componentPropertyBinder,
+                collectionBinder,
+                propertyFromValueCreator,
+                new SimpleValueBinder(namingStrategy),
+                new ColumnNameForPropertyAndPathFetcher(namingStrategy),
+                new OneToOneBinder(namingStrategy),
+                new ManyToOneBinder(namingStrategy));
+    }
+
+    protected GrailsPropertyBinder(
+            MetadataBuildingContext metadataBuildingContext,
+            PersistentEntityNamingStrategy namingStrategy,
+            CollectionHolder collectionHolder,
+            EnumTypeBinder enumTypeBinder,
+            ComponentPropertyBinder componentPropertyBinder,
+            CollectionBinder collectionBinder,
+            PropertyFromValueCreator propertyFromValueCreator,
+            SimpleValueBinder simpleValueBinder,
+            ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher,
+            OneToOneBinder oneToOneBinder,
+            ManyToOneBinder manyToOneBinder) {
         this.metadataBuildingContext = metadataBuildingContext;
         this.namingStrategy = namingStrategy;
         this.collectionHolder = collectionHolder;
@@ -54,6 +83,10 @@ public class GrailsPropertyBinder {
         this.componentPropertyBinder = componentPropertyBinder;
         this.collectionBinder = collectionBinder;
         this.propertyFromValueCreator = propertyFromValueCreator;
+        this.simpleValueBinder = simpleValueBinder;
+        this.columnNameForPropertyAndPathFetcher = 
columnNameForPropertyAndPathFetcher;
+        this.oneToOneBinder = oneToOneBinder;
+        this.manyToOneBinder = manyToOneBinder;
     }
 
     public void bindProperty(PersistentClass persistentClass
@@ -77,12 +110,12 @@ public class GrailsPropertyBinder {
         if (currentGrailsProp.isUserButNotCollectionType()) {
             value = new BasicValue(metadataBuildingContext, table);
             // No specific binder call needed for this case per original logic
-            new 
SimpleValueBinder(namingStrategy).bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);
+            simpleValueBinder.bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);
         }
         else if (collectionType != null) {
             if (currentGrailsProp.isSerializableType()) {
                 value = new BasicValue(metadataBuildingContext, table);
-                new 
SimpleValueBinder(namingStrategy).bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);// No specific binder call needed
+                simpleValueBinder.bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);// No specific binder call needed
             }
             else { // Actual Collection
                 Collection collection = 
collectionType.create((HibernateToManyProperty) currentGrailsProp, 
persistentClass,
@@ -97,17 +130,17 @@ public class GrailsPropertyBinder {
             value = new BasicValue(metadataBuildingContext, table);
             // Apply enumTypeBinder if the created value is a SimpleValue
             SimpleValue simpleValue = (SimpleValue) value;
-            String columnName = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy).getColumnNameForPropertyAndPath(currentGrailsProp,
 EMPTY_PATH, null);
+            String columnName = 
columnNameForPropertyAndPathFetcher.getColumnNameForPropertyAndPath(currentGrailsProp,
 EMPTY_PATH, null);
             enumTypeBinder.bindEnumType(currentGrailsProp, 
currentGrailsProp.getType(), simpleValue, columnName);
         }
         else if (currentGrailsProp.isHibernateOneToOne()) {
             value = new OneToOne(metadataBuildingContext, table, 
persistentClass);
             // Apply OneToOneBinder logic
-            new 
OneToOneBinder(namingStrategy).bindOneToOne((org.grails.datastore.mapping.model.types.OneToOne)currentGrailsProp,
 (OneToOne)value, EMPTY_PATH);
+            
oneToOneBinder.bindOneToOne((org.grails.datastore.mapping.model.types.OneToOne)currentGrailsProp,
 (OneToOne)value, EMPTY_PATH);
         } else if(currentGrailsProp.isHibernateManyToOne()) {
             value = new ManyToOne(metadataBuildingContext, table);
             // Apply ManyToOneBinder logic
-            new 
ManyToOneBinder(namingStrategy).bindManyToOne((Association)currentGrailsProp, 
(ManyToOne)value, EMPTY_PATH);
+            manyToOneBinder.bindManyToOne((Association)currentGrailsProp, 
(ManyToOne)value, EMPTY_PATH);
         }
         else if (currentGrailsProp instanceof Embedded) {
             value = new Component(metadataBuildingContext, persistentClass);
@@ -117,7 +150,7 @@ public class GrailsPropertyBinder {
         // work out what type of relationship it is and bind value
         else { // Default BasicValue
             value = new BasicValue(metadataBuildingContext, table);
-            new 
SimpleValueBinder(namingStrategy).bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);
+            simpleValueBinder.bindSimpleValue(currentGrailsProp, 
null,(SimpleValue) value, EMPTY_PATH);
         }
 
         // After creating the value and applying binders (where applicable), 
create and add the property.
@@ -127,4 +160,4 @@ public class GrailsPropertyBinder {
             persistentClass.addProperty(property);
         }
     }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
index b8fddef382..ab4324a6a4 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/GrailsPropertyBinderSpec.groovy
@@ -278,6 +278,58 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         oneToOne.referencedEntityName == bookEntity.name
     }
 
+    void "should use binders from protected constructor"() {
+        given:
+        def metadataBuildingContext = 
Mock(org.hibernate.boot.spi.MetadataBuildingContext)
+        def namingStrategy = 
Mock(org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy)
+        // CollectionHolder is a Java record (final), so we instantiate it
+        def collectionHolder = new 
org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder(new 
HashMap<Class<?>, 
org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionType>())
+        def enumTypeBinder = Mock(EnumTypeBinder)
+        def componentPropertyBinder = Mock(ComponentPropertyBinder)
+        def collectionBinder = Mock(CollectionBinder)
+        def propertyFromValueCreator = Mock(PropertyFromValueCreator)
+        def simpleValueBinder = Mock(SimpleValueBinder)
+        def columnNameForPropertyAndPathFetcher = 
Mock(ColumnNameForPropertyAndPathFetcher)
+        def oneToOneBinder = Mock(OneToOneBinder)
+        def manyToOneBinder = Mock(ManyToOneBinder)
+
+        def propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                collectionHolder,
+                enumTypeBinder,
+                componentPropertyBinder,
+                collectionBinder,
+                propertyFromValueCreator,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder
+        )
+
+        def mappings = Mock(org.hibernate.boot.spi.InFlightMetadataCollector)
+        metadataBuildingContext.getMetadataCollector() >> mappings
+
+        def rootClass = new RootClass(metadataBuildingContext)
+        def currentGrailsProp = Mock(GrailsHibernatePersistentProperty)
+        def table = new org.hibernate.mapping.Table("TEST_TABLE")
+        rootClass.setTable(table)
+        def owner = 
Mock(org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity)
+
+        currentGrailsProp.getHibernateOwner() >> owner
+        owner.getMappedForm() >> new org.grails.orm.hibernate.cfg.Mapping()
+        currentGrailsProp.getType() >> String.class
+        currentGrailsProp.getName() >> "title"
+
+        propertyFromValueCreator.createProperty(_ as 
org.hibernate.mapping.Value, currentGrailsProp) >> new Property()
+
+        when:
+        propertyBinder.bindProperty(rootClass, mappings, "sessionFactory", 
currentGrailsProp)
+
+        then:
+        1 * simpleValueBinder.bindSimpleValue(currentGrailsProp, null, _ as 
SimpleValue, "")
+    }
+
 
 }
 

Reply via email to