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())
