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 e68727c2056bc24d404c43af8b1b4e98110a2b6c
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Thu Feb 19 12:28:22 2026 -0600

    Extract SubclassMappingBinder and add spec
---
 .../domainbinding/binder/GrailsDomainBinder.java   |  41 +-------
 .../binder/SubclassMappingBinder.java              |  71 +++++++++++++
 .../binder/SubclassMappingBinderSpec.groovy        | 111 +++++++++++++++++++++
 3 files changed, 184 insertions(+), 39 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
index c9133b9675..1943517cf5 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
@@ -288,7 +288,8 @@ public class GrailsDomainBinder
                               @Nonnull InFlightMetadataCollector mappings,
                               Mapping m, MappingCacheHolder 
mappingCacheHolder, DefaultColumnNameFetcher defaultColumnNameFetcher, 
ClassBinder classBinder, ClassPropertiesBinder classPropertiesBinder, 
MultiTenantFilterBinder multiTenantFilterBinder, JoinedSubClassBinder 
joinedSubClassBinder, UnionSubclassBinder unionSubclassBinder, 
SingleTableSubclassBinder singleTableSubclassBinder) {
         mappingCacheHolder.cacheMapping(sub);
-        Subclass subClass = createSubclassMapping(sub, parent, mappings, m, 
defaultColumnNameFetcher, classPropertiesBinder, joinedSubClassBinder, 
unionSubclassBinder, singleTableSubclassBinder);
+        SubclassMappingBinder subclassMappingBinder = new 
SubclassMappingBinder(metadataBuildingContext, joinedSubClassBinder, 
unionSubclassBinder, singleTableSubclassBinder, classPropertiesBinder);
+        Subclass subClass = subclassMappingBinder.createSubclassMapping(sub, 
parent, mappings, m);
 
 
         parent.addSubclass(subClass);
@@ -303,44 +304,6 @@ public class GrailsDomainBinder
         }
     }
 
-    private @NonNull Subclass createSubclassMapping(@NonNull 
GrailsHibernatePersistentEntity subEntity
-            , PersistentClass parent
-            , @NonNull InFlightMetadataCollector mappings
-            , Mapping m
-            , DefaultColumnNameFetcher defaultColumnNameFetcher
-            ,ClassPropertiesBinder classPropertiesBinder
-            ,JoinedSubClassBinder joinedSubClassBinder
-            , UnionSubclassBinder unionSubclassBinder
-            , SingleTableSubclassBinder singleTableSubclassBinder) {
-        Subclass subClass;
-        subEntity.configureDerivedProperties();
-        if (!m.getTablePerHierarchy() && !m.isTablePerConcreteClass()) {
-            var joined = new JoinedSubclass(parent, 
this.metadataBuildingContext);
-            joinedSubClassBinder.bindJoinedSubClass(subEntity, joined, 
mappings);
-            subClass = joined;
-        }
-        else if(m.isTablePerConcreteClass()) {
-            var union  = new UnionSubclass(parent, 
this.metadataBuildingContext);
-            unionSubclassBinder.bindUnionSubclass(subEntity, union, mappings);
-            subClass = union;
-        }
-        else {
-            var singleTableSubclass = new SingleTableSubclass(parent, 
this.metadataBuildingContext);
-
-            singleTableSubclassBinder.bindSubClass(subEntity, 
singleTableSubclass, mappings);
-            subClass = singleTableSubclass;
-        }
-        
subClass.setBatchSize(Optional.ofNullable(m.getBatchSize()).orElse(-1));
-        subClass.setDynamicUpdate(m.getDynamicUpdate());
-        subClass.setDynamicInsert(m.getDynamicInsert());
-        subClass.setCached(parent.isCached());
-        subClass.setAbstract(subEntity.isAbstract());
-        subClass.setEntityName(subEntity.getName());
-        
subClass.setJpaEntityName(GrailsHibernateUtil.unqualify(subEntity.getName()));
-        classPropertiesBinder.bindClassProperties(subEntity, subClass, 
mappings);
-        return subClass;
-    }
-
 
     /**
      * Binds a sub-class using table-per-hierarchy inheritance mapping
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
new file mode 100644
index 0000000000..67ff7438cf
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinder.java
@@ -0,0 +1,71 @@
+package org.grails.orm.hibernate.cfg.domainbinding.binder;
+
+import jakarta.annotation.Nonnull;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.grails.orm.hibernate.cfg.GrailsHibernateUtil;
+import org.grails.orm.hibernate.cfg.Mapping;
+import 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity;
+import org.hibernate.boot.spi.InFlightMetadataCollector;
+import org.hibernate.boot.spi.MetadataBuildingContext;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.UnionSubclass;
+
+import java.util.Optional;
+
+public class SubclassMappingBinder {
+
+    private final MetadataBuildingContext metadataBuildingContext;
+    private final JoinedSubClassBinder joinedSubClassBinder;
+    private final UnionSubclassBinder unionSubclassBinder;
+    private final SingleTableSubclassBinder singleTableSubclassBinder;
+    private final ClassPropertiesBinder classPropertiesBinder;
+
+    public SubclassMappingBinder(
+            MetadataBuildingContext metadataBuildingContext,
+            JoinedSubClassBinder joinedSubClassBinder,
+            UnionSubclassBinder unionSubclassBinder,
+            SingleTableSubclassBinder singleTableSubclassBinder,
+            ClassPropertiesBinder classPropertiesBinder) {
+        this.metadataBuildingContext = metadataBuildingContext;
+        this.joinedSubClassBinder = joinedSubClassBinder;
+        this.unionSubclassBinder = unionSubclassBinder;
+        this.singleTableSubclassBinder = singleTableSubclassBinder;
+        this.classPropertiesBinder = classPropertiesBinder;
+    }
+
+    public @NonNull Subclass createSubclassMapping(@NonNull 
GrailsHibernatePersistentEntity subEntity
+            , PersistentClass parent
+            , @NonNull InFlightMetadataCollector mappings
+            , Mapping m) {
+        Subclass subClass;
+        subEntity.configureDerivedProperties();
+        if (!m.getTablePerHierarchy() && !m.isTablePerConcreteClass()) {
+            var joined = new JoinedSubclass(parent, 
this.metadataBuildingContext);
+            joinedSubClassBinder.bindJoinedSubClass(subEntity, joined, 
mappings);
+            subClass = joined;
+        }
+        else if(m.isTablePerConcreteClass()) {
+            var union  = new UnionSubclass(parent, 
this.metadataBuildingContext);
+            unionSubclassBinder.bindUnionSubclass(subEntity, union, mappings);
+            subClass = union;
+        }
+        else {
+            var singleTableSubclass = new SingleTableSubclass(parent, 
this.metadataBuildingContext);
+
+            singleTableSubclassBinder.bindSubClass(subEntity, 
singleTableSubclass, mappings);
+            subClass = singleTableSubclass;
+        }
+        
subClass.setBatchSize(Optional.ofNullable(m.getBatchSize()).orElse(-1));
+        subClass.setDynamicUpdate(m.getDynamicUpdate());
+        subClass.setDynamicInsert(m.getDynamicInsert());
+        subClass.setCached(parent.isCached());
+        subClass.setAbstract(subEntity.isAbstract());
+        subClass.setEntityName(subEntity.getName());
+        
subClass.setJpaEntityName(GrailsHibernateUtil.unqualify(subEntity.getName()));
+        classPropertiesBinder.bindClassProperties(subEntity, subClass, 
mappings);
+        return subClass;
+    }
+}
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
new file mode 100644
index 0000000000..3936ae8e3e
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubclassMappingBinderSpec.groovy
@@ -0,0 +1,111 @@
+package org.grails.orm.hibernate.cfg.domainbinding.binder
+
+import grails.gorm.annotation.Entity
+import grails.gorm.specs.HibernateGormDatastoreSpec
+import org.grails.orm.hibernate.cfg.Mapping
+import org.hibernate.boot.spi.MetadataBuildingContext
+import org.hibernate.mapping.JoinedSubclass
+import org.hibernate.mapping.PersistentClass
+import org.hibernate.mapping.RootClass
+import org.hibernate.mapping.SingleTableSubclass
+import org.hibernate.mapping.Subclass
+import org.hibernate.mapping.UnionSubclass
+import spock.lang.Shared
+
+class SubclassMappingBinderSpec extends HibernateGormDatastoreSpec {
+
+    SubclassMappingBinder binder
+    MetadataBuildingContext metadataBuildingContext
+    JoinedSubClassBinder joinedSubClassBinder
+    UnionSubclassBinder unionSubclassBinder
+    SingleTableSubclassBinder singleTableSubclassBinder
+    ClassPropertiesBinder classPropertiesBinder
+
+    void setup() {
+        manager.addAllDomainClasses([SMBSDefaultSuperEntity, 
SMBSDefaultSubEntity])
+        def gdb = getGrailsDomainBinder()
+        metadataBuildingContext = gdb.getMetadataBuildingContext()
+        joinedSubClassBinder = Mock(JoinedSubClassBinder)
+        unionSubclassBinder = Mock(UnionSubclassBinder)
+        singleTableSubclassBinder = Mock(SingleTableSubclassBinder)
+        classPropertiesBinder = Mock(ClassPropertiesBinder)
+        
+        binder = new SubclassMappingBinder(
+                metadataBuildingContext,
+                joinedSubClassBinder,
+                unionSubclassBinder,
+                singleTableSubclassBinder,
+                classPropertiesBinder
+        )
+    }
+
+    def "test createSubclassMapping for single table inheritance"() {
+        given:
+        def subEntity = createPersistentEntity(SMBSDefaultSubEntity) as 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        def rootClass = new RootClass(metadataBuildingContext)
+        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        def mappings = getCollector()
+        def mapping = new Mapping()
+        mapping.setTablePerHierarchy(true)
+
+        when:
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, 
mappings, mapping)
+
+        then:
+        1 * singleTableSubclassBinder.bindSubClass(subEntity, _ as 
SingleTableSubclass, mappings)
+        1 * classPropertiesBinder.bindClassProperties(subEntity, _ as 
Subclass, mappings)
+        subClass instanceof SingleTableSubclass
+        subClass.getEntityName() == SMBSDefaultSubEntity.name
+    }
+
+    def "test createSubclassMapping for joined table inheritance"() {
+        given:
+        def subEntity = getPersistentEntity(SMBSDefaultSubEntity) as 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        def rootClass = new RootClass(metadataBuildingContext)
+        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        def mappings = getCollector()
+        def mapping = new Mapping()
+        mapping.@tablePerHierarchy = false
+        mapping.@tablePerConcreteClass = false
+
+        when:
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, 
mappings, mapping)
+
+        then:
+        1 * joinedSubClassBinder.bindJoinedSubClass(subEntity, _ as 
JoinedSubclass, mappings)
+        1 * classPropertiesBinder.bindClassProperties(subEntity, _ as 
Subclass, mappings)
+        subClass instanceof JoinedSubclass
+        subClass.getEntityName() == SMBSDefaultSubEntity.name
+    }
+
+    def "test createSubclassMapping for table per concrete class 
inheritance"() {
+        given:
+        def subEntity = getPersistentEntity(SMBSDefaultSubEntity) as 
org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity
+        def rootClass = new RootClass(metadataBuildingContext)
+        rootClass.setEntityName(SMBSDefaultSuperEntity.name)
+        def mappings = getCollector()
+        def mapping = new Mapping()
+        mapping.@tablePerHierarchy = false
+        mapping.@tablePerConcreteClass = true
+
+        when:
+        Subclass subClass = binder.createSubclassMapping(subEntity, rootClass, 
mappings, mapping)
+
+        then:
+        1 * unionSubclassBinder.bindUnionSubclass(subEntity, _ as 
UnionSubclass, mappings)
+        1 * classPropertiesBinder.bindClassProperties(subEntity, _ as 
Subclass, mappings)
+        subClass instanceof UnionSubclass
+        subClass.getEntityName() == SMBSDefaultSubEntity.name
+    }
+}
+
+@Entity
+class SMBSDefaultSuperEntity {
+    Long id
+    String name
+}
+
+@Entity
+class SMBSDefaultSubEntity extends SMBSDefaultSuperEntity {
+    String subName
+}

Reply via email to