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 95d1a3fb4b84cd4cf77222894c67a1db6120d4d3 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Thu Feb 19 11:48:31 2026 -0600 Extract RootPersistentClassCommonValuesBinder and update specs --- .../domainbinding/binder/GrailsDomainBinder.java | 68 +-------------- .../RootPersistentClassCommonValuesBinder.java | 97 +++++++++++++++++++++ .../cfg/domainbinding/CollectionBinderSpec.groovy | 2 +- .../domainbinding/GrailsPropertyBinderSpec.groovy | 2 +- ...ootPersistentClassCommonValuesBinderSpec.groovy | 98 ++++++++++++++++++++++ .../secondpass/ListSecondPassBinderSpec.groovy | 2 +- .../secondpass/MapSecondPassBinderSpec.groovy | 2 +- 7 files changed, 203 insertions(+), 68 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 9ec54d8df1..05323e231f 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 @@ -213,7 +213,7 @@ public class GrailsDomainBinder .getHibernatePersistentEntities(dataSourceName) .stream() .filter(persistentEntity -> persistentEntity.forGrailsDomainMapping(dataSourceName)) - .forEach(hibernatePersistentEntity -> bindRoot(hibernatePersistentEntity, metadataCollector, sessionFactoryName, defaultColumnNameFetcher, identityBinder, versionBinder, classBinder, classPropertiesBinder, multiTenantFilterBinder, joinedSubClassBinder, unionSubclassBinder, singleTableSubclassBinder)); + .forEach(hibernatePersistentEntity -> bindRoot(hibernatePersistentEntity, metadataCollector, defaultColumnNameFetcher, identityBinder, versionBinder, classBinder, classPropertiesBinder, multiTenantFilterBinder, joinedSubClassBinder, unionSubclassBinder, singleTableSubclassBinder)); } @@ -244,13 +244,14 @@ 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, IdentityBinder identityBinder, VersionBinder versionBinder, ClassBinder classBinder, ClassPropertiesBinder classPropertiesBinder, MultiTenantFilterBinder multiTenantFilterBinder, JoinedSubClassBinder joinedSubClassBinder, UnionSubclassBinder unionSubclassBinder, SingleTableSubclassBinder [...] + protected void bindRoot(@Nonnull GrailsHibernatePersistentEntity entity,@Nonnull InFlightMetadataCollector mappings, DefaultColumnNameFetcher defaultColumnNameFetcher, IdentityBinder identityBinder, VersionBinder versionBinder, ClassBinder classBinder, ClassPropertiesBinder classPropertiesBinder, MultiTenantFilterBinder multiTenantFilterBinder, JoinedSubClassBinder joinedSubClassBinder, UnionSubclassBinder unionSubclassBinder, SingleTableSubclassBinder singleTableSubclassBinder) { if (mappings.getEntityBinding(entity.getName()) != null) { LOG.info("[GrailsDomainBinder] Class [" + entity.getName() + "] is already mapped, skipping.. "); return; } + RootPersistentClassCommonValuesBinder rootPersistentClassCommonValuesBinder = new RootPersistentClassCommonValuesBinder(metadataBuildingContext, getNamingStrategy(), identityBinder, versionBinder, classBinder, classPropertiesBinder); var children = entity.getChildEntities(dataSourceName); - RootClass root = bindRootPersistentClassCommonValues(entity, children, mappings, identityBinder, versionBinder, classBinder, classPropertiesBinder); + RootClass root = rootPersistentClassCommonValuesBinder.bindRootPersistentClassCommonValues(entity, children, mappings); Mapping m = entity.getMappedForm(); final Mapping finalMapping = m; if (!children.isEmpty() && entity.isTablePerHierarchy()) { @@ -398,67 +399,6 @@ public class GrailsDomainBinder } } - /* - * Binds a persistent classes to the table representation and binds the class properties - */ - private RootClass bindRootPersistentClassCommonValues(@Nonnull GrailsHibernatePersistentEntity domainClass, - @Nonnull Collection<GrailsHibernatePersistentEntity> children, - @Nonnull InFlightMetadataCollector mappings, - IdentityBinder identityBinder, - VersionBinder versionBinder, - ClassBinder classBinder, - ClassPropertiesBinder classPropertiesBinder - ) { - - RootClass root = new RootClass(this.metadataBuildingContext); - root.setAbstract(domainClass.isAbstract()); - classBinder.bindClass(domainClass, root, mappings); - - // get the schema and catalog names from the configuration - Mapping gormMapping = domainClass.getMappedForm(); - - domainClass.configureDerivedProperties(); - CacheConfig cc = gormMapping.getCache(); - if (cc != null && cc.getEnabled()) { - root.setCacheConcurrencyStrategy(cc.getUsage()); - root.setCached(true); - if ("read-only".equals(cc.getUsage())) { - root.setMutable(false); - } - root.setLazyPropertiesCacheable(!"non-lazy".equals(cc.getInclude())); - } - root.setBatchSize(ofNullable(gormMapping.getBatchSize()).orElse(0)); - root.setDynamicUpdate(gormMapping.getDynamicUpdate()); - root.setDynamicInsert(gormMapping.getDynamicInsert()); - - - var schema = domainClass.getSchema(mappings); - - var catalog = domainClass.getCatalog(mappings); - - - // create the table - var table = mappings.addTable(schema - , catalog - , domainClass.getTableName(getNamingStrategy()) - , null - , domainClass.isTableAbstract() - , metadataBuildingContext - ); - root.setTable(table); - if (LOG.isDebugEnabled()) { - LOG.debug("[GrailsDomainBinder] Mapping Grails domain class: " + domainClass.getName() + " -> " + root.getTable().getName()); - } - - identityBinder.bindIdentity(domainClass, root, mappings, gormMapping); - versionBinder.bindVersion(domainClass.getVersion(), root); - root.createPrimaryKey(); - classPropertiesBinder.bindClassProperties(domainClass, root, mappings); - - return root; - } - - public MetadataBuildingContext getMetadataBuildingContext() { return metadataBuildingContext; } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java new file mode 100644 index 0000000000..6fb19e4713 --- /dev/null +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java @@ -0,0 +1,97 @@ +package org.grails.orm.hibernate.cfg.domainbinding.binder; + +import jakarta.annotation.Nonnull; +import org.grails.orm.hibernate.cfg.CacheConfig; +import org.grails.orm.hibernate.cfg.GrailsHibernateUtil; +import org.grails.orm.hibernate.cfg.Mapping; +import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; +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.RootClass; +import org.hibernate.mapping.Table; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +public class RootPersistentClassCommonValuesBinder { + public static final Logger LOG = LoggerFactory.getLogger(RootPersistentClassCommonValuesBinder.class); + + private final MetadataBuildingContext metadataBuildingContext; + private final PersistentEntityNamingStrategy namingStrategy; + private final IdentityBinder identityBinder; + private final VersionBinder versionBinder; + private final ClassBinder classBinder; + private final ClassPropertiesBinder classPropertiesBinder; + + public RootPersistentClassCommonValuesBinder( + MetadataBuildingContext metadataBuildingContext, + PersistentEntityNamingStrategy namingStrategy, + IdentityBinder identityBinder, + VersionBinder versionBinder, + ClassBinder classBinder, + ClassPropertiesBinder classPropertiesBinder) { + this.metadataBuildingContext = metadataBuildingContext; + this.namingStrategy = namingStrategy; + this.identityBinder = identityBinder; + this.versionBinder = versionBinder; + this.classBinder = classBinder; + this.classPropertiesBinder = classPropertiesBinder; + } + + public RootClass bindRootPersistentClassCommonValues(@Nonnull GrailsHibernatePersistentEntity domainClass, + @Nonnull Collection<GrailsHibernatePersistentEntity> children, + @Nonnull InFlightMetadataCollector mappings) { + + RootClass root = new RootClass(this.metadataBuildingContext); + root.setAbstract(domainClass.isAbstract()); + classBinder.bindClass(domainClass, root, mappings); + + // get the schema and catalog names from the configuration + Mapping gormMapping = domainClass.getMappedForm(); + + domainClass.configureDerivedProperties(); + CacheConfig cc = gormMapping.getCache(); + if (cc != null && cc.getEnabled()) { + root.setCacheConcurrencyStrategy(cc.getUsage()); + root.setCached(true); + if ("read-only".equals(cc.getUsage())) { + root.setMutable(false); + } + root.setLazyPropertiesCacheable(!"non-lazy".equals(cc.getInclude())); + } + root.setBatchSize(ofNullable(gormMapping.getBatchSize()).orElse(0)); + root.setDynamicUpdate(gormMapping.getDynamicUpdate()); + root.setDynamicInsert(gormMapping.getDynamicInsert()); + + + var schema = domainClass.getSchema(mappings); + + var catalog = domainClass.getCatalog(mappings); + + + // create the table + var table = mappings.addTable(schema + , catalog + , domainClass.getTableName(namingStrategy) + , null + , domainClass.isTableAbstract() + , metadataBuildingContext + ); + root.setTable(table); + if (LOG.isDebugEnabled()) { + LOG.debug("[GrailsDomainBinder] Mapping Grails domain class: " + domainClass.getName() + " -> " + root.getTable().getName()); + } + + identityBinder.bindIdentity(domainClass, root, mappings, gormMapping); + versionBinder.bindVersion(domainClass.getVersion(), root); + root.createPrimaryKey(); + classPropertiesBinder.bindClassProperties(domainClass, root, mappings); + + return root; + } +} 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 f2c1c83ef7..090fd9e286 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 @@ -135,7 +135,7 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec { protected void bindRoot(GrailsDomainBinder binder, GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { def binders = getBinders(binder) - binder.bindRoot(entity, mappings, sessionFactoryBeanName, + binder.bindRoot(entity, mappings, binders.defaultColumnNameFetcher, binders.identityBinder as IdentityBinder, binders.versionBinder as VersionBinder, 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 06b7dbe03f..299a32c857 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 @@ -196,7 +196,7 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec { protected void bindRoot(GrailsDomainBinder binder, GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { def binders = getBinders(binder) - binder.bindRoot(entity, mappings, sessionFactoryBeanName, + binder.bindRoot(entity, mappings, binders.defaultColumnNameFetcher, binders.identityBinder as IdentityBinder, binders.versionBinder as VersionBinder, diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinderSpec.groovy new file mode 100644 index 0000000000..5ff513e0a8 --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinderSpec.groovy @@ -0,0 +1,98 @@ +package org.grails.orm.hibernate.cfg.domainbinding.binder + +import grails.gorm.annotation.Entity +import grails.gorm.specs.HibernateGormDatastoreSpec +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.util.BasicValueIdCreator +import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover +import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher +import org.grails.orm.hibernate.cfg.Mapping +import org.grails.datastore.mapping.model.PersistentEntity +import org.hibernate.mapping.SimpleValue +import org.hibernate.mapping.Column +import org.hibernate.mapping.Table +import org.hibernate.mapping.BasicValue + +class RootPersistentClassCommonValuesBinderSpec extends HibernateGormDatastoreSpec { + + RootPersistentClassCommonValuesBinder binder + MetadataBuildingContext metadataBuildingContext + PersistentEntityNamingStrategy namingStrategy + IdentityBinder identityBinder + VersionBinder versionBinder + ClassBinder classBinder + ClassPropertiesBinder classPropertiesBinder + GrailsDomainBinder gormDomainBinder + + void setup() { + manager.addAllDomainClasses([TestEntity, AbstractTestEntity]) + + gormDomainBinder = getGrailsDomainBinder() + metadataBuildingContext = gormDomainBinder.getMetadataBuildingContext() + namingStrategy = gormDomainBinder.getNamingStrategy() + def jdbcEnvironment = gormDomainBinder.getJdbcEnvironment() + def simpleValueBinder = new SimpleValueBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment) + def propertyBinder = new PropertyBinder() + def simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinder) + def compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, null, null, null) + identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder) + versionBinder = new VersionBinder(metadataBuildingContext, simpleValueBinder, propertyBinder, BasicValue::new) + classBinder = new ClassBinder() + classPropertiesBinder = Mock(ClassPropertiesBinder) + + binder = new RootPersistentClassCommonValuesBinder( + metadataBuildingContext, + namingStrategy, + identityBinder, + versionBinder, + classBinder, + classPropertiesBinder + ) + } + + void "test bindRootPersistentClassCommonValues binds properties correctly"() { + given: + def entity = createPersistentEntity(TestEntity) + def mappings = getCollector() + + when: + RootClass rootClass = binder.bindRootPersistentClassCommonValues(entity, [], mappings) + + then: + 1 * classPropertiesBinder.bindClassProperties(entity, _, mappings) + rootClass != null + rootClass.getEntityName() == TestEntity.name + rootClass.isAbstract() == false + rootClass.getTable().getName() == namingStrategy.resolveTableName("TestEntity") + } + + void "test bindRootPersistentClassCommonValues for abstract entity"() { + given: + def entity = createPersistentEntity(AbstractTestEntity) + def mappings = getCollector() + + when: + RootClass rootClass = binder.bindRootPersistentClassCommonValues(entity, [], mappings) + + then: + rootClass != null + rootClass.isAbstract() == true + } +} + +@Entity +class TestEntity { + Long id + Long version + String name +} + +@Entity +abstract class AbstractTestEntity { + Long id + Long version + String name +} diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/ListSecondPassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/ListSecondPassBinderSpec.groovy index a710e70159..7aea0465ee 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/ListSecondPassBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/ListSecondPassBinderSpec.groovy @@ -134,7 +134,7 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec { protected void bindRoot(GrailsDomainBinder binder, GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { def binders = getBinders(binder) - binder.bindRoot(entity, mappings, sessionFactoryBeanName, + binder.bindRoot(entity, mappings, binders.defaultColumnNameFetcher, binders.identityBinder as IdentityBinder, binders.versionBinder as VersionBinder, diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/MapSecondPassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/MapSecondPassBinderSpec.groovy index 1d066f7d3a..3a0ec3fde4 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/MapSecondPassBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/MapSecondPassBinderSpec.groovy @@ -134,7 +134,7 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec { protected void bindRoot(GrailsDomainBinder binder, GrailsHibernatePersistentEntity entity, InFlightMetadataCollector mappings, String sessionFactoryBeanName) { def binders = getBinders(binder) - binder.bindRoot(entity, mappings, sessionFactoryBeanName, + binder.bindRoot(entity, mappings, binders.defaultColumnNameFetcher, binders.identityBinder as IdentityBinder, binders.versionBinder as VersionBinder,
