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 c2e74db3971907a9eff44e173e0ac5d08e4f1f97
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Feb 14 14:21:05 2026 -0600

    Refactor binders in GrailsDomainBinder to be local variables
    
    - Convert collectionBinder, componentPropertyBinder, grailsPropertyBinder, 
compositeIdBinder, identityBinder, and versionBinder to local variables in the 
contribute method.
    - Update binding method signatures to accept these binders as parameters.
    - Update unit tests to instantiate these binders via helper methods and 
pass them to bindRoot.
---
 .../orm/hibernate/cfg/GrailsDomainBinder.java      |  82 +++++---------
 .../cfg/domainbinding/CollectionBinderSpec.groovy  | 111 ++++++++++++++++++-
 .../CollectionSecondPassBinderSpec.groovy          | 112 ++++++++++++++++++-
 .../domainbinding/GrailsPropertyBinderSpec.groovy  | 123 +++++++++++++++++++--
 .../domainbinding/ListSecondPassBinderSpec.groovy  | 112 ++++++++++++++++++-
 .../domainbinding/MapSecondPassBinderSpec.groovy   | 112 ++++++++++++++++++-
 6 files changed, 581 insertions(+), 71 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
index 89ac71987d..9e37b89f25 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
@@ -134,12 +134,6 @@ public class GrailsDomainBinder
     private MetadataBuildingContext metadataBuildingContext;
     private MappingCacheHolder mappingCacheHolder;
     private CollectionHolder collectionHolder;
-    private GrailsPropertyBinder grailsPropertyBinder;
-    private CollectionBinder collectionBinder;
-    private CompositeIdBinder compositeIdBinder;
-    private IdentityBinder identityBinder;
-    private VersionBinder versionBinder;
-    private ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher;
 
 
     public JdbcEnvironment getJdbcEnvironment() {
@@ -197,7 +191,7 @@ public class GrailsDomainBinder
         PersistentEntityNamingStrategy namingStrategy = getNamingStrategy();
         JdbcEnvironment jdbcEnvironment = getJdbcEnvironment();
         DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover);
-        this.columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover);
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover);
         SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment);
         EnumTypeBinder enumTypeBinderToUse = enumTypeBinder != null ? 
enumTypeBinder : new EnumTypeBinder();
         SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher();
@@ -212,7 +206,7 @@ public class GrailsDomainBinder
         OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder);
         ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher);
 
-        this.collectionBinder = new CollectionBinder(
+        CollectionBinder collectionBinder = new CollectionBinder(
                 metadataBuildingContext,
                 this,
                 namingStrategy,
@@ -223,7 +217,7 @@ public class GrailsDomainBinder
                 compositeIdentifierToManyToOneBinder,
                 simpleValueColumnFetcher
         );
-        this.componentPropertyBinder = new ComponentPropertyBinder(
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
                 metadataBuildingContext,
                 namingStrategy,
                 jdbcEnvironment,
@@ -238,7 +232,7 @@ public class GrailsDomainBinder
                 manyToOneBinder,
                 columnNameForPropertyAndPathFetcher
         );
-        this.grailsPropertyBinder = new GrailsPropertyBinder(
+        GrailsPropertyBinder grailsPropertyBinder = new GrailsPropertyBinder(
                 metadataBuildingContext,
                 namingStrategy,
                 getCollectionHolder(),
@@ -251,17 +245,17 @@ public class GrailsDomainBinder
                 manyToOneBinder,
                 propertyFromValueCreator
         );
-        this.compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder);
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder);
         PropertyBinder propertyBinder = new PropertyBinder();
         SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinder);
-        this.identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder);
-        this.versionBinder = new VersionBinder(metadataBuildingContext, 
simpleValueBinder, propertyBinder, BasicValue::new);
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder);
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinder, 
BasicValue::new);
 
         hibernateMappingContext
                 .getHibernatePersistentEntities(dataSourceName)
                 .stream()
                 .filter(persistentEntity -> 
persistentEntity.forGrailsDomainMapping(dataSourceName))
-                .forEach(hibernatePersistentEntity -> 
bindRoot(hibernatePersistentEntity, metadataCollector, sessionFactoryName, 
defaultColumnNameFetcher));
+                .forEach(hibernatePersistentEntity -> 
bindRoot(hibernatePersistentEntity, metadataCollector, sessionFactoryName, 
defaultColumnNameFetcher, columnNameForPropertyAndPathFetcher, identityBinder, 
versionBinder, grailsPropertyBinder));
     }
 
 
@@ -292,13 +286,13 @@ public class GrailsDomainBinder
      * @param mappings    The Hibernate Mappings object
      * @param sessionFactoryBeanName  the session factory bean name
      */
-    protected void bindRoot(@Nonnull GrailsHibernatePersistentEntity 
entity,@Nonnull InFlightMetadataCollector mappings, String 
sessionFactoryBeanName, DefaultColumnNameFetcher defaultColumnNameFetcher) {
+    protected void bindRoot(@Nonnull GrailsHibernatePersistentEntity 
entity,@Nonnull InFlightMetadataCollector mappings, String 
sessionFactoryBeanName, DefaultColumnNameFetcher defaultColumnNameFetcher, 
ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher, 
IdentityBinder identityBinder, VersionBinder versionBinder, 
GrailsPropertyBinder grailsPropertyBinder) {
         if (mappings.getEntityBinding(entity.getName()) != null) {
             LOG.info("[GrailsDomainBinder] Class [" + entity.getName() + "] is 
already mapped, skipping.. ");
             return;
         }
         var children = entity.getChildEntities(dataSourceName);
-        RootClass root = bindRootPersistentClassCommonValues(entity, children, 
mappings, sessionFactoryBeanName);
+        RootClass root = bindRootPersistentClassCommonValues(entity, children, 
mappings, sessionFactoryBeanName, identityBinder, versionBinder, 
grailsPropertyBinder);
         if (root.isPolymorphic()) {
             Mapping m = entity.getMappedForm();
             final Mapping finalMapping = m;
@@ -309,7 +303,7 @@ public class GrailsDomainBinder
                 bindDiscriminatorProperty(root.getTable(), root, m);
             }
             // bind the sub classes
-            children.forEach(sub -> bindSubClass(sub, root, mappings, 
sessionFactoryBeanName, finalMapping,mappingCacheHolder, 
defaultColumnNameFetcher ));
+            children.forEach(sub -> bindSubClass(sub, root, mappings, 
sessionFactoryBeanName, finalMapping,mappingCacheHolder, 
defaultColumnNameFetcher, columnNameForPropertyAndPathFetcher, 
grailsPropertyBinder ));
         }
 
         addMultiTenantFilterIfNecessary(entity, root, mappings, 
defaultColumnNameFetcher);
@@ -380,9 +374,9 @@ public class GrailsDomainBinder
                               PersistentClass parent,
                               @Nonnull InFlightMetadataCollector mappings,
                               String sessionFactoryBeanName
-                            , Mapping m, MappingCacheHolder 
mappingCacheHolder, DefaultColumnNameFetcher defaultColumnNameFetcher) {
+                            , Mapping m, MappingCacheHolder 
mappingCacheHolder, DefaultColumnNameFetcher defaultColumnNameFetcher, 
ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher, 
GrailsPropertyBinder grailsPropertyBinder) {
         mappingCacheHolder.cacheMapping(sub);
-        Subclass subClass = createSubclassMapping(sub, parent, mappings, 
sessionFactoryBeanName, m, defaultColumnNameFetcher);
+        Subclass subClass = createSubclassMapping(sub, parent, mappings, 
sessionFactoryBeanName, m, defaultColumnNameFetcher, 
columnNameForPropertyAndPathFetcher, grailsPropertyBinder);
 
 
         parent.addSubclass(subClass);
@@ -393,25 +387,25 @@ public class GrailsDomainBinder
         var children = sub.getChildEntities(dataSourceName);
         if (!children.isEmpty()) {
             // bind the sub classes
-            children.forEach(sub1 -> bindSubClass(sub1, subClass, mappings, 
sessionFactoryBeanName, m,mappingCacheHolder, defaultColumnNameFetcher ));
+            children.forEach(sub1 -> bindSubClass(sub1, subClass, mappings, 
sessionFactoryBeanName, m,mappingCacheHolder, defaultColumnNameFetcher, 
columnNameForPropertyAndPathFetcher, grailsPropertyBinder ));
         }
     }
 
-    private @NonNull Subclass createSubclassMapping(@NonNull 
GrailsHibernatePersistentEntity subEntity, PersistentClass parent, @NonNull 
InFlightMetadataCollector mappings, String sessionFactoryBeanName, Mapping m, 
DefaultColumnNameFetcher defaultColumnNameFetcher) {
+    private @NonNull Subclass createSubclassMapping(@NonNull 
GrailsHibernatePersistentEntity subEntity, PersistentClass parent, @NonNull 
InFlightMetadataCollector mappings, String sessionFactoryBeanName, Mapping m, 
DefaultColumnNameFetcher defaultColumnNameFetcher, 
ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher, 
GrailsPropertyBinder grailsPropertyBinder) {
         Subclass subClass;
         subEntity.configureDerivedProperties();
         if (!m.getTablePerHierarchy() && !m.isTablePerConcreteClass()) {
             subClass = new JoinedSubclass(parent, 
this.metadataBuildingContext);
-            bindJoinedSubClass(subEntity, (JoinedSubclass) subClass, mappings, 
sessionFactoryBeanName);
+            bindJoinedSubClass(subEntity, (JoinedSubclass) subClass, mappings, 
sessionFactoryBeanName, columnNameForPropertyAndPathFetcher, 
grailsPropertyBinder);
         }
         else if(m.isTablePerConcreteClass()) {
             subClass = new UnionSubclass(parent, this.metadataBuildingContext);
-            bindUnionSubclass(subEntity, (UnionSubclass) subClass, mappings, 
sessionFactoryBeanName);
+            bindUnionSubclass(subEntity, (UnionSubclass) subClass, mappings, 
sessionFactoryBeanName, grailsPropertyBinder);
         }
         else {
             subClass = new SingleTableSubclass(parent, 
this.metadataBuildingContext);
             subClass.setDiscriminatorValue(subEntity.getDiscriminatorValue());
-            bindSubClass(subEntity, subClass, mappings, 
sessionFactoryBeanName, defaultColumnNameFetcher);
+            bindSubClass(subEntity, subClass, mappings, 
sessionFactoryBeanName, defaultColumnNameFetcher, grailsPropertyBinder);
         }
         
subClass.setBatchSize(Optional.ofNullable(m.getBatchSize()).orElse(-1));
         subClass.setDynamicUpdate(m.getDynamicUpdate());
@@ -425,7 +419,7 @@ public class GrailsDomainBinder
 
 
     private void bindUnionSubclass(@Nonnull GrailsHibernatePersistentEntity 
subClass, UnionSubclass unionSubclass,
-                                  @Nonnull InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) throws MappingException {
+                                  @Nonnull InFlightMetadataCollector mappings, 
String sessionFactoryBeanName, GrailsPropertyBinder grailsPropertyBinder) 
throws MappingException {
         classBinding.bindClass(subClass, unionSubclass, mappings);
 
         String schema = subClass.getSchema(mappings);
@@ -448,7 +442,7 @@ public class GrailsDomainBinder
                         " -> " + unionSubclass.getTable().getName()
         );
 
-        createClassProperties(subClass, unionSubclass, mappings, 
sessionFactoryBeanName);
+        createClassProperties(subClass, unionSubclass, mappings, 
sessionFactoryBeanName, grailsPropertyBinder);
 
     }
     /**
@@ -460,7 +454,7 @@ public class GrailsDomainBinder
      * @param sessionFactoryBeanName the session factory bean name
      */
     private void bindJoinedSubClass(GrailsHibernatePersistentEntity sub, 
JoinedSubclass joinedSubclass,
-                                    InFlightMetadataCollector mappings, String 
sessionFactoryBeanName) {
+                                    InFlightMetadataCollector mappings, String 
sessionFactoryBeanName, ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher, GrailsPropertyBinder grailsPropertyBinder) 
{
         classBinding.bindClass(sub, joinedSubclass, mappings);
 
         String schemaName = sub.getSchema(mappings);
@@ -485,7 +479,7 @@ public class GrailsDomainBinder
         joinedSubclass.createForeignKey();
 
         // properties
-        createClassProperties(sub, joinedSubclass, mappings, 
sessionFactoryBeanName);
+        createClassProperties(sub, joinedSubclass, mappings, 
sessionFactoryBeanName, grailsPropertyBinder);
     }
 
     private String getJoinedSubClassTableName(
@@ -510,7 +504,7 @@ public class GrailsDomainBinder
      * @param mappings The mappings instance
      */
     private void bindSubClass(@Nonnull GrailsHibernatePersistentEntity sub, 
Subclass subClass, @Nonnull InFlightMetadataCollector mappings,
-                                String sessionFactoryBeanName, 
DefaultColumnNameFetcher defaultColumnNameFetcher) {
+                                String sessionFactoryBeanName, 
DefaultColumnNameFetcher defaultColumnNameFetcher, GrailsPropertyBinder 
grailsPropertyBinder) {
         classBinding.bindClass(sub, subClass, mappings);
 
         if (LOG.isDebugEnabled())
@@ -518,7 +512,7 @@ public class GrailsDomainBinder
                     " -> " + subClass.getTable().getName());
 
         // properties
-        createClassProperties(sub, subClass, mappings, sessionFactoryBeanName);
+        createClassProperties(sub, subClass, mappings, sessionFactoryBeanName, 
grailsPropertyBinder);
     }
 
     /**
@@ -580,7 +574,10 @@ public class GrailsDomainBinder
     private RootClass bindRootPersistentClassCommonValues(@Nonnull 
GrailsHibernatePersistentEntity domainClass,
                                                        @Nonnull 
java.util.Collection<GrailsHibernatePersistentEntity> children,
                                                        @Nonnull 
InFlightMetadataCollector mappings,
-                                                       String 
sessionFactoryBeanName
+                                                       String 
sessionFactoryBeanName,
+                                                       IdentityBinder 
identityBinder,
+                                                       VersionBinder 
versionBinder,
+                                                       GrailsPropertyBinder 
grailsPropertyBinder
     ) {
 
         RootClass root = new RootClass(this.metadataBuildingContext);
@@ -629,7 +626,7 @@ public class GrailsDomainBinder
         identityBinder.bindIdentity(domainClass, root, mappings, gormMapping, 
sessionFactoryBeanName);
         versionBinder.bindVersion(domainClass.getVersion(), root);
         root.createPrimaryKey();
-        createClassProperties(domainClass, root, mappings, 
sessionFactoryBeanName);
+        createClassProperties(domainClass, root, mappings, 
sessionFactoryBeanName, grailsPropertyBinder);
 
         return root;
     }
@@ -645,7 +642,7 @@ public class GrailsDomainBinder
      * @param sessionFactoryBeanName  the session factory bean name
      */
     private void createClassProperties(@Nonnull 
GrailsHibernatePersistentEntity domainClass, PersistentClass persistentClass,
-                                         @Nonnull InFlightMetadataCollector 
mappings, String sessionFactoryBeanName) {
+                                         @Nonnull InFlightMetadataCollector 
mappings, String sessionFactoryBeanName, GrailsPropertyBinder 
grailsPropertyBinder) {
 
 
 
@@ -676,25 +673,6 @@ public class GrailsDomainBinder
         return propertyFromValueCreator;
     }
 
-    public GrailsPropertyBinder getGrailsPropertyBinder() {
-        return grailsPropertyBinder;
-    }
-
-    public CollectionBinder getCollectionBinder() {
-        return collectionBinder;
-    }
-
-    public CompositeIdBinder getCompositeIdBinder() {
-        return compositeIdBinder;
-    }
-
-    public IdentityBinder getIdentityBinder() {
-        return identityBinder;
-    }
-
-    public VersionBinder getVersionBinder() {
-        return versionBinder;
-    }
 
     @Override
     public String getContributorName() {
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinderSpec.groovy
index e1dd19fdb6..31c0bef73a 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinderSpec.groovy
@@ -6,9 +6,118 @@ import 
org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty
 import org.hibernate.mapping.OneToMany
 import org.hibernate.mapping.RootClass
 import org.hibernate.mapping.Set
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.TableNameFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder
+import org.grails.orm.hibernate.cfg.GrailsDomainBinder
+
+import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
+import org.hibernate.boot.spi.InFlightMetadataCollector
+import org.grails.orm.hibernate.cfg.domainbinding.binder.VersionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.PropertyBinder
+import org.hibernate.mapping.BasicValue
+import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover
+import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
+import 
org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator
 
 class CollectionBinderSpec extends HibernateGormDatastoreSpec {
 
+    protected Map getBinders(GrailsDomainBinder binder) {
+        MetadataBuildingContext metadataBuildingContext = 
binder.getMetadataBuildingContext()
+        PersistentEntityNamingStrategy namingStrategy = 
binder.getNamingStrategy()
+        JdbcEnvironment jdbcEnvironment = binder.getJdbcEnvironment()
+        BackticksRemover backticksRemover = new BackticksRemover()
+        DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover)
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover)
+        SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment)
+        EnumTypeBinder enumTypeBinderToUse = new EnumTypeBinder()
+        SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher()
+        CompositeIdentifierToManyToOneBinder 
compositeIdentifierToManyToOneBinder = new CompositeIdentifierToManyToOneBinder(
+                new 
org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator(),
+                new TableNameFetcher(namingStrategy),
+                namingStrategy,
+                defaultColumnNameFetcher,
+                backticksRemover,
+                simpleValueBinder
+        )
+        OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder)
+        ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher)
+
+        CollectionBinder collectionBinder = new CollectionBinder(
+                metadataBuildingContext,
+                binder,
+                namingStrategy,
+                jdbcEnvironment,
+                simpleValueBinder,
+                enumTypeBinderToUse,
+                manyToOneBinder,
+                compositeIdentifierToManyToOneBinder,
+                simpleValueColumnFetcher
+        )
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                jdbcEnvironment,
+                binder.getMappingCacheHolder(),
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                collectionBinder,
+                new PropertyFromValueCreator(),
+                null,
+                simpleValueBinder,
+                oneToOneBinder,
+                manyToOneBinder,
+                columnNameForPropertyAndPathFetcher
+        )
+        GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                componentPropertyBinder,
+                collectionBinder,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder,
+                new PropertyFromValueCreator()
+        )
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+        PropertyBinder propertyBinderHelper = new PropertyBinder()
+        SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper)
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder)
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinderHelper, 
BasicValue::new)
+
+        return [
+            propertyBinder: propertyBinder,
+            collectionBinder: collectionBinder,
+            identityBinder: identityBinder,
+            versionBinder: versionBinder,
+            defaultColumnNameFetcher: defaultColumnNameFetcher,
+            columnNameForPropertyAndPathFetcher: 
columnNameForPropertyAndPathFetcher
+        ]
+    }
+
+    protected void bindRoot(GrailsDomainBinder binder, 
GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) {
+        def binders = getBinders(binder)
+        binder.bindRoot(entity, mappings, sessionFactoryBeanName, 
binders.defaultColumnNameFetcher, binders.columnNameForPropertyAndPathFetcher, 
binders.identityBinder as IdentityBinder, binders.versionBinder as 
VersionBinder, binders.propertyBinder as GrailsPropertyBinder)
+    }
+
     void setupSpec() {
         manager.addAllDomainClasses([
             org.apache.grails.data.testing.tck.domains.Pet,
@@ -20,7 +129,7 @@ class CollectionBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind collection"() {
         given:
         def binder = getGrailsDomainBinder()
-        def collectionBinder = binder.getCollectionBinder()
+        def collectionBinder = getBinders(binder).collectionBinder
         def collector = getCollector()
 
         def personEntity = 
getPersistentEntity(org.apache.grails.data.testing.tck.domains.Person) as 
GrailsHibernatePersistentEntity
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionSecondPassBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionSecondPassBinderSpec.groovy
index 6af22f62d1..cd46b537a6 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionSecondPassBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionSecondPassBinderSpec.groovy
@@ -5,14 +5,121 @@ import grails.gorm.specs.HibernateGormDatastoreSpec
 import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity
 import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty
 import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover
+import 
org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher
 import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
 
 import org.hibernate.mapping.RootClass
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.TableNameFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder
+import org.grails.orm.hibernate.cfg.GrailsDomainBinder
 
 import 
org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder
 
+import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator
+import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
+import org.hibernate.boot.spi.InFlightMetadataCollector
+import org.grails.orm.hibernate.cfg.domainbinding.binder.VersionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.PropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
+import org.hibernate.mapping.BasicValue
+
 class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec {
 
+    protected Map getBinders(GrailsDomainBinder binder) {
+        MetadataBuildingContext metadataBuildingContext = 
binder.getMetadataBuildingContext()
+        PersistentEntityNamingStrategy namingStrategy = 
binder.getNamingStrategy()
+        JdbcEnvironment jdbcEnvironment = binder.getJdbcEnvironment()
+        BackticksRemover backticksRemover = new BackticksRemover()
+        DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover)
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover)
+        SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment)
+        EnumTypeBinder enumTypeBinderToUse = new EnumTypeBinder()
+        SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher()
+        CompositeIdentifierToManyToOneBinder 
compositeIdentifierToManyToOneBinder = new CompositeIdentifierToManyToOneBinder(
+                new 
org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator(),
+                new TableNameFetcher(namingStrategy),
+                namingStrategy,
+                defaultColumnNameFetcher,
+                backticksRemover,
+                simpleValueBinder
+        )
+        OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder)
+        ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher)
+
+        CollectionBinder collectionBinder = new CollectionBinder(
+                metadataBuildingContext,
+                binder,
+                namingStrategy,
+                jdbcEnvironment,
+                simpleValueBinder,
+                enumTypeBinderToUse,
+                manyToOneBinder,
+                compositeIdentifierToManyToOneBinder,
+                simpleValueColumnFetcher
+        )
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                jdbcEnvironment,
+                binder.getMappingCacheHolder(),
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                collectionBinder,
+                new PropertyFromValueCreator(),
+                null,
+                simpleValueBinder,
+                oneToOneBinder,
+                manyToOneBinder,
+                columnNameForPropertyAndPathFetcher
+        )
+        GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                componentPropertyBinder,
+                collectionBinder,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder,
+                new PropertyFromValueCreator()
+        )
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+        PropertyBinder propertyBinderHelper = new PropertyBinder()
+        SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper)
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder)
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinderHelper, 
BasicValue::new)
+
+        return [
+            propertyBinder: propertyBinder,
+            collectionBinder: collectionBinder,
+            identityBinder: identityBinder,
+            versionBinder: versionBinder,
+            defaultColumnNameFetcher: defaultColumnNameFetcher,
+            columnNameForPropertyAndPathFetcher: 
columnNameForPropertyAndPathFetcher
+        ]
+    }
+
+    protected void bindRoot(GrailsDomainBinder binder, 
GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) {
+        def binders = getBinders(binder)
+        binder.bindRoot(entity, mappings, sessionFactoryBeanName, 
binders.defaultColumnNameFetcher, binders.columnNameForPropertyAndPathFetcher, 
binders.identityBinder as IdentityBinder, binders.versionBinder as 
VersionBinder, binders.propertyBinder as GrailsPropertyBinder)
+    }
+
     void setupSpec() {
         manager.addAllDomainClasses([
                 Author,
@@ -24,7 +131,8 @@ class CollectionSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def collectionBinder = binder.getCollectionBinder()
+        def binders = getBinders(binder)
+        def collectionBinder = binders.collectionBinder
         def namingStrategy = binder.getNamingStrategy()
         def jdbcEnvironment = binder.getJdbcEnvironment()
         def collectionSecondPassBinder = new CollectionSecondPassBinder(
@@ -42,7 +150,7 @@ class CollectionSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         def bookEntity = getPersistentEntity(Book) as 
GrailsHibernatePersistentEntity
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
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 dba76ebbe5..4449b59ca1 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
@@ -23,8 +23,107 @@ import 
org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndP
 import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
 import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
 
+import org.hibernate.mapping.BasicValue
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.TableNameFetcher
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder
+
+import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.VersionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.PropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator
+import org.hibernate.boot.spi.InFlightMetadataCollector
+
 class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
 
+    protected Map getBinders(GrailsDomainBinder binder) {
+        MetadataBuildingContext metadataBuildingContext = 
binder.getMetadataBuildingContext()
+        PersistentEntityNamingStrategy namingStrategy = 
binder.getNamingStrategy()
+        JdbcEnvironment jdbcEnvironment = binder.getJdbcEnvironment()
+        BackticksRemover backticksRemover = new BackticksRemover()
+        DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover)
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover)
+        SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment)
+        EnumTypeBinder enumTypeBinderToUse = new EnumTypeBinder()
+        SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher()
+        CompositeIdentifierToManyToOneBinder 
compositeIdentifierToManyToOneBinder = new CompositeIdentifierToManyToOneBinder(
+                new 
org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator(),
+                new TableNameFetcher(namingStrategy),
+                namingStrategy,
+                defaultColumnNameFetcher,
+                backticksRemover,
+                simpleValueBinder
+        )
+        OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder)
+        ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher)
+
+        CollectionBinder collectionBinder = new CollectionBinder(
+                metadataBuildingContext,
+                binder,
+                namingStrategy,
+                jdbcEnvironment,
+                simpleValueBinder,
+                enumTypeBinderToUse,
+                manyToOneBinder,
+                compositeIdentifierToManyToOneBinder,
+                simpleValueColumnFetcher
+        )
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                jdbcEnvironment,
+                binder.getMappingCacheHolder(),
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                collectionBinder,
+                new PropertyFromValueCreator(),
+                null,
+                simpleValueBinder,
+                oneToOneBinder,
+                manyToOneBinder,
+                columnNameForPropertyAndPathFetcher
+        )
+        GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                componentPropertyBinder,
+                collectionBinder,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder,
+                new PropertyFromValueCreator()
+        )
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+        PropertyBinder propertyBinderHelper = new PropertyBinder()
+        SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper)
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder)
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinderHelper, 
BasicValue::new)
+
+        return [
+            propertyBinder: propertyBinder,
+            collectionBinder: collectionBinder,
+            identityBinder: identityBinder,
+            versionBinder: versionBinder,
+            defaultColumnNameFetcher: defaultColumnNameFetcher,
+            columnNameForPropertyAndPathFetcher: 
columnNameForPropertyAndPathFetcher
+        ]
+    }
+
+    protected void bindRoot(GrailsDomainBinder binder, 
GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) {
+        def binders = getBinders(binder)
+        binder.bindRoot(entity, mappings, sessionFactoryBeanName, 
binders.defaultColumnNameFetcher, binders.columnNameForPropertyAndPathFetcher, 
binders.identityBinder as IdentityBinder, binders.versionBinder as 
VersionBinder, binders.propertyBinder as GrailsPropertyBinder)
+    }
+
     void setupSpec() {
         manager.addAllDomainClasses([
             org.apache.grails.data.testing.tck.domains.Pet,
@@ -38,7 +137,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def persistentEntity = createPersistentEntity(binder, "SimpleBook", 
[title: String], [:])
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
         rootClass.setEntityName(persistentEntity.name)
@@ -61,7 +160,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def persistentEntity = createPersistentEntity(binder, "EnumBook", 
[status: java.util.concurrent.TimeUnit], [:])
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
         rootClass.setEntityName(persistentEntity.name)
@@ -83,7 +182,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind many-to-one"() {
         given:
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def collector = getCollector()
 
         def petEntity = 
getPersistentEntity(org.apache.grails.data.testing.tck.domains.Pet) as 
GrailsHibernatePersistentEntity
@@ -109,7 +208,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         
         def persistentEntity = createPersistentEntity(binder, "Employee", 
[name: String, homeAddress: Address], [:], ["homeAddress"])
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
@@ -134,7 +233,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind set collection"() {
         given:
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def collector = getCollector()
 
         def personEntity = 
getPersistentEntity(org.apache.grails.data.testing.tck.domains.Person) as 
GrailsHibernatePersistentEntity
@@ -161,14 +260,14 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind list collection"() {
         given:
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def collector = getCollector()
 
         def bookEntity = createPersistentEntity(ListBook)
         def authorEntity = createPersistentEntity(ListAuthor)
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity to avoid duplicate 
property binding
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
@@ -201,14 +300,14 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind map collection"() {
         given:
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def collector = getCollector()
 
         def bookEntity = createPersistentEntity(MapBook)
         def authorEntity = createPersistentEntity(MapAuthor)
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
@@ -245,7 +344,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         def personEntity = 
getPersistentEntity(org.apache.grails.data.testing.tck.domains.PersonWithCompositeKey)
 as GrailsHibernatePersistentEntity
         
         when:
-        binder.bindRoot(personEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, personEntity, collector, "sessionFactory")
         def rootClass = collector.getEntityBinding(personEntity.name)
 
         then:
@@ -260,7 +359,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
     void "Test bind one-to-one property"() {
         given:
         def binder = getGrailsDomainBinder()
-        def propertyBinder = binder.getGrailsPropertyBinder()
+        def propertyBinder = getBinders(binder).propertyBinder
         def collector = getCollector()
 
         // Create two entities: Author (with hasOne child) and Book (the child)
@@ -268,7 +367,7 @@ class GrailsPropertyBinderSpec extends 
HibernateGormDatastoreSpec {
         def bookEntity = createPersistentEntity(BookForOneToOne) as 
GrailsHibernatePersistentEntity
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity (AuthorWithOneToOne)
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ListSecondPassBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ListSecondPassBinderSpec.groovy
index 66d07c71ba..7bf27fe3e4 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ListSecondPassBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ListSecondPassBinderSpec.groovy
@@ -5,16 +5,123 @@ import grails.gorm.specs.HibernateGormDatastoreSpec
 import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity
 import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty
 import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover
+import 
org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher
 import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
 
 import org.hibernate.mapping.RootClass
 import org.hibernate.mapping.SimpleValue
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.TableNameFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder
+import org.grails.orm.hibernate.cfg.GrailsDomainBinder
 
 import 
org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder
 import 
org.grails.orm.hibernate.cfg.domainbinding.secondpass.ListSecondPassBinder
 
+import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator
+import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
+import org.hibernate.boot.spi.InFlightMetadataCollector
+import org.grails.orm.hibernate.cfg.domainbinding.binder.VersionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.PropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
+import org.hibernate.mapping.BasicValue
+
 class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec {
 
+    protected Map getBinders(GrailsDomainBinder binder) {
+        MetadataBuildingContext metadataBuildingContext = 
binder.getMetadataBuildingContext()
+        PersistentEntityNamingStrategy namingStrategy = 
binder.getNamingStrategy()
+        JdbcEnvironment jdbcEnvironment = binder.getJdbcEnvironment()
+        BackticksRemover backticksRemover = new BackticksRemover()
+        DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover)
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover)
+        SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment)
+        EnumTypeBinder enumTypeBinderToUse = new EnumTypeBinder()
+        SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher()
+        CompositeIdentifierToManyToOneBinder 
compositeIdentifierToManyToOneBinder = new CompositeIdentifierToManyToOneBinder(
+                new 
org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator(),
+                new TableNameFetcher(namingStrategy),
+                namingStrategy,
+                defaultColumnNameFetcher,
+                backticksRemover,
+                simpleValueBinder
+        )
+        OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder)
+        ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher)
+
+        CollectionBinder collectionBinder = new CollectionBinder(
+                metadataBuildingContext,
+                binder,
+                namingStrategy,
+                jdbcEnvironment,
+                simpleValueBinder,
+                enumTypeBinderToUse,
+                manyToOneBinder,
+                compositeIdentifierToManyToOneBinder,
+                simpleValueColumnFetcher
+        )
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                jdbcEnvironment,
+                binder.getMappingCacheHolder(),
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                collectionBinder,
+                new PropertyFromValueCreator(),
+                null,
+                simpleValueBinder,
+                oneToOneBinder,
+                manyToOneBinder,
+                columnNameForPropertyAndPathFetcher
+        )
+        GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                componentPropertyBinder,
+                collectionBinder,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder,
+                new PropertyFromValueCreator()
+        )
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+        PropertyBinder propertyBinderHelper = new PropertyBinder()
+        SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper)
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder)
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinderHelper, 
BasicValue::new)
+
+        return [
+            propertyBinder: propertyBinder,
+            collectionBinder: collectionBinder,
+            identityBinder: identityBinder,
+            versionBinder: versionBinder,
+            defaultColumnNameFetcher: defaultColumnNameFetcher,
+            columnNameForPropertyAndPathFetcher: 
columnNameForPropertyAndPathFetcher
+        ]
+    }
+
+    protected void bindRoot(GrailsDomainBinder binder, 
GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) {
+        def binders = getBinders(binder)
+        binder.bindRoot(entity, mappings, sessionFactoryBeanName, 
binders.defaultColumnNameFetcher, binders.columnNameForPropertyAndPathFetcher, 
binders.identityBinder as IdentityBinder, binders.versionBinder as 
VersionBinder, binders.propertyBinder as GrailsPropertyBinder)
+    }
+
     void setupSpec() {
         manager.addAllDomainClasses([
                 ListBinderAuthor,
@@ -26,7 +133,8 @@ class ListSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def collectionBinder = binder.getCollectionBinder()
+        def binders = getBinders(binder)
+        def collectionBinder = binders.collectionBinder
         def namingStrategy = binder.getNamingStrategy()
         def jdbcEnvironment = binder.getJdbcEnvironment()
         def collectionSecondPassBinder = new CollectionSecondPassBinder(
@@ -45,7 +153,7 @@ class ListSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         def bookEntity = getPersistentEntity(ListBinderBook) as 
GrailsHibernatePersistentEntity
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity
         def rootClass = new RootClass(binder.getMetadataBuildingContext())
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/MapSecondPassBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/MapSecondPassBinderSpec.groovy
index 7d58f13e90..1a921437bb 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/MapSecondPassBinderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/MapSecondPassBinderSpec.groovy
@@ -5,16 +5,123 @@ import grails.gorm.specs.HibernateGormDatastoreSpec
 import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity
 import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty
 import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover
+import 
org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher
 import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
 
 import org.hibernate.mapping.RootClass
 import org.hibernate.mapping.SimpleValue
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.util.TableNameFetcher
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder
+import org.grails.orm.hibernate.cfg.GrailsDomainBinder
 
 import 
org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionSecondPassBinder
 import 
org.grails.orm.hibernate.cfg.domainbinding.secondpass.MapSecondPassBinder
 
+import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder
+import 
org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator
+import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
+import org.hibernate.boot.spi.InFlightMetadataCollector
+import org.grails.orm.hibernate.cfg.domainbinding.binder.VersionBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.PropertyBinder
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
+import org.hibernate.mapping.BasicValue
+
 class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec {
 
+    protected Map getBinders(GrailsDomainBinder binder) {
+        MetadataBuildingContext metadataBuildingContext = 
binder.getMetadataBuildingContext()
+        PersistentEntityNamingStrategy namingStrategy = 
binder.getNamingStrategy()
+        JdbcEnvironment jdbcEnvironment = binder.getJdbcEnvironment()
+        BackticksRemover backticksRemover = new BackticksRemover()
+        DefaultColumnNameFetcher defaultColumnNameFetcher = new 
DefaultColumnNameFetcher(namingStrategy, backticksRemover)
+        ColumnNameForPropertyAndPathFetcher 
columnNameForPropertyAndPathFetcher = new 
ColumnNameForPropertyAndPathFetcher(namingStrategy, defaultColumnNameFetcher, 
backticksRemover)
+        SimpleValueBinder simpleValueBinder = new 
SimpleValueBinder(namingStrategy, jdbcEnvironment)
+        EnumTypeBinder enumTypeBinderToUse = new EnumTypeBinder()
+        SimpleValueColumnFetcher simpleValueColumnFetcher = new 
SimpleValueColumnFetcher()
+        CompositeIdentifierToManyToOneBinder 
compositeIdentifierToManyToOneBinder = new CompositeIdentifierToManyToOneBinder(
+                new 
org.grails.orm.hibernate.cfg.domainbinding.util.ForeignKeyColumnCountCalculator(),
+                new TableNameFetcher(namingStrategy),
+                namingStrategy,
+                defaultColumnNameFetcher,
+                backticksRemover,
+                simpleValueBinder
+        )
+        OneToOneBinder oneToOneBinder = new OneToOneBinder(namingStrategy, 
simpleValueBinder)
+        ManyToOneBinder manyToOneBinder = new ManyToOneBinder(namingStrategy, 
simpleValueBinder, new ManyToOneValuesBinder(), 
compositeIdentifierToManyToOneBinder, simpleValueColumnFetcher)
+
+        CollectionBinder collectionBinder = new CollectionBinder(
+                metadataBuildingContext,
+                binder,
+                namingStrategy,
+                jdbcEnvironment,
+                simpleValueBinder,
+                enumTypeBinderToUse,
+                manyToOneBinder,
+                compositeIdentifierToManyToOneBinder,
+                simpleValueColumnFetcher
+        )
+        ComponentPropertyBinder componentPropertyBinder = new 
ComponentPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                jdbcEnvironment,
+                binder.getMappingCacheHolder(),
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                collectionBinder,
+                new PropertyFromValueCreator(),
+                null,
+                simpleValueBinder,
+                oneToOneBinder,
+                manyToOneBinder,
+                columnNameForPropertyAndPathFetcher
+        )
+        GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
+                metadataBuildingContext,
+                namingStrategy,
+                binder.getCollectionHolder(),
+                enumTypeBinderToUse,
+                componentPropertyBinder,
+                collectionBinder,
+                simpleValueBinder,
+                columnNameForPropertyAndPathFetcher,
+                oneToOneBinder,
+                manyToOneBinder,
+                new PropertyFromValueCreator()
+        )
+        CompositeIdBinder compositeIdBinder = new 
CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+        PropertyBinder propertyBinderHelper = new PropertyBinder()
+        SimpleIdBinder simpleIdBinder = new 
SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new 
BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper)
+        IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, 
compositeIdBinder)
+        VersionBinder versionBinder = new 
VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinderHelper, 
BasicValue::new)
+
+        return [
+            propertyBinder: propertyBinder,
+            collectionBinder: collectionBinder,
+            identityBinder: identityBinder,
+            versionBinder: versionBinder,
+            defaultColumnNameFetcher: defaultColumnNameFetcher,
+            columnNameForPropertyAndPathFetcher: 
columnNameForPropertyAndPathFetcher
+        ]
+    }
+
+    protected void bindRoot(GrailsDomainBinder binder, 
GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, 
String sessionFactoryBeanName) {
+        def binders = getBinders(binder)
+        binder.bindRoot(entity, mappings, sessionFactoryBeanName, 
binders.defaultColumnNameFetcher, binders.columnNameForPropertyAndPathFetcher, 
binders.identityBinder as IdentityBinder, binders.versionBinder as 
VersionBinder, binders.propertyBinder as GrailsPropertyBinder)
+    }
+
     void setupSpec() {
         manager.addAllDomainClasses([
                 MapAuthorBinder,
@@ -26,7 +133,8 @@ class MapSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         given:
         def collector = getCollector()
         def binder = getGrailsDomainBinder()
-        def collectionBinder = binder.getCollectionBinder()
+        def binders = getBinders(binder)
+        def collectionBinder = binders.collectionBinder
         def namingStrategy = binder.getNamingStrategy()
         def jdbcEnvironment = binder.getJdbcEnvironment()
         def collectionSecondPassBinder = new CollectionSecondPassBinder(
@@ -45,7 +153,7 @@ class MapSecondPassBinderSpec extends 
HibernateGormDatastoreSpec {
         def bookEntity = getPersistentEntity(MapBookBinder) as 
GrailsHibernatePersistentEntity
 
         // Register referenced entity in Hibernate
-        binder.bindRoot(bookEntity, collector, "sessionFactory", new 
DefaultColumnNameFetcher(binder.getNamingStrategy(), new BackticksRemover()))
+        bindRoot(binder, bookEntity, collector, "sessionFactory")
 
         // Manually create RootClass for the main entity
         def rootClass = new RootClass(binder.getMetadataBuildingContext())

Reply via email to