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 84500c9a2d405903059437010c33d99197930ef4 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Sun Feb 15 23:11:40 2026 -0600 Merge ComponentPropertyBinder into ComponentBinder - Consolidate all component property binding logic into ComponentBinder. - Enable recursive component binding by having ComponentBinder call its own methods for embedded properties. - Remove redundant ComponentPropertyBinder and its associated test specification. - Update GrailsDomainBinder and CompositeIdBinder to use the consolidated ComponentBinder. - Migrate and update unit tests to ensure continued coverage of property binding logic within ComponentBinderSpec. --- .../orm/hibernate/cfg/GrailsDomainBinder.java | 8 +- .../cfg/domainbinding/binder/ComponentBinder.java | 104 +++++++- .../binder/ComponentPropertyBinder.java | 124 ---------- .../domainbinding/binder/CompositeIdBinder.java | 8 +- .../cfg/domainbinding/CollectionBinderSpec.groovy | 8 +- .../CollectionSecondPassBinderSpec.groovy | 8 +- .../cfg/domainbinding/ComponentBinderSpec.groovy | 251 +++++++++++++++++++- .../ComponentPropertyBinderSpec.groovy | 263 --------------------- .../cfg/domainbinding/CompositeIdBinderSpec.groovy | 10 +- .../domainbinding/GrailsPropertyBinderSpec.groovy | 12 +- .../domainbinding/ListSecondPassBinderSpec.groovy | 8 +- .../domainbinding/MapSecondPassBinderSpec.groovy | 8 +- 12 files changed, 368 insertions(+), 444 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 332fbac39a..0b639d8e0a 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 @@ -18,7 +18,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassPropertiesBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnConfigToColumnBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder; -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater; import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder; @@ -185,8 +184,9 @@ public class GrailsDomainBinder simpleValueColumnFetcher ); ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator); - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, + getMappingCacheHolder(), collectionHolder, enumTypeBinder, collectionBinder, @@ -196,8 +196,6 @@ public class GrailsDomainBinder columnNameForPropertyAndPathFetcher, componentUpdater ); - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, getMappingCacheHolder(), componentPropertyBinder); - componentPropertyBinder.setComponentBinder(componentBinder); GrailsPropertyBinder grailsPropertyBinder = new GrailsPropertyBinder( metadataBuildingContext, @@ -212,7 +210,7 @@ public class GrailsDomainBinder manyToOneBinder, propertyFromValueCreator ); - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder); + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder); PropertyBinder propertyBinder = new PropertyBinder(); SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinder); IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentBinder.java index 753c1066c5..818406b9f0 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentBinder.java @@ -2,29 +2,67 @@ package org.grails.orm.hibernate.cfg.domainbinding.binder; import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.mapping.BasicValue; +import org.hibernate.mapping.Collection; import org.hibernate.mapping.Component; +import org.hibernate.mapping.ManyToOne; +import org.hibernate.mapping.OneToOne; import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; +import org.hibernate.mapping.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.grails.datastore.mapping.model.config.GormProperties; +import org.grails.datastore.mapping.model.types.Association; import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty; import org.grails.orm.hibernate.cfg.GrailsHibernateUtil; import org.grails.orm.hibernate.cfg.MappingCacheHolder; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty; +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; +import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder; +import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionType; +import org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher; import jakarta.annotation.Nonnull; public class ComponentBinder { + private static final Logger LOG = LoggerFactory.getLogger(ComponentBinder.class); + private final MetadataBuildingContext metadataBuildingContext; private final MappingCacheHolder mappingCacheHolder; - private final ComponentPropertyBinder componentPropertyBinder; + private final CollectionHolder collectionHolder; + private final EnumTypeBinder enumTypeBinder; + private final CollectionBinder collectionBinder; + private final ManyToOneBinder manyToOneBinder; + private final OneToOneBinder oneToOneBinder; + private final ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher; + private final SimpleValueBinder simpleValueBinder; + private final ComponentUpdater componentUpdater; - public ComponentBinder(MetadataBuildingContext metadataBuildingContext, MappingCacheHolder mappingCacheHolder, ComponentPropertyBinder componentPropertyBinder) { + public ComponentBinder(MetadataBuildingContext metadataBuildingContext, + MappingCacheHolder mappingCacheHolder, + CollectionHolder collectionHolder, + EnumTypeBinder enumTypeBinder, + CollectionBinder collectionBinder, + SimpleValueBinder simpleValueBinder, + OneToOneBinder oneToOneBinder, + ManyToOneBinder manyToOneBinder, + ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher, + ComponentUpdater componentUpdater) { this.metadataBuildingContext = metadataBuildingContext; this.mappingCacheHolder = mappingCacheHolder; - this.componentPropertyBinder = componentPropertyBinder; + this.collectionHolder = collectionHolder; + this.enumTypeBinder = enumTypeBinder; + this.collectionBinder = collectionBinder; + this.simpleValueBinder = simpleValueBinder; + this.oneToOneBinder = oneToOneBinder; + this.manyToOneBinder = manyToOneBinder; + this.columnNameForPropertyAndPathFetcher = columnNameForPropertyAndPathFetcher; + this.componentUpdater = componentUpdater; } @@ -52,9 +90,67 @@ public class ComponentBinder { component.setParentProperty(currentGrailsProp.getName()); continue; } - componentPropertyBinder.bindComponentProperty(component, property, currentGrailsProp, persistentClass, path, table, mappings); + bindComponentProperty(component, property, currentGrailsProp, persistentClass, path, table, mappings); } return component; } + + public Value bindComponentProperty(Component component, + GrailsHibernatePersistentProperty componentProperty, + GrailsHibernatePersistentProperty currentGrailsProp, + PersistentClass persistentClass, + String path, + Table table, + @Nonnull InFlightMetadataCollector mappings) { + Value value; + // see if it's a collection type + CollectionType collectionType = collectionHolder.get(currentGrailsProp.getType()); + if (collectionType != null) { + // create collection + Collection collection = collectionType.create((HibernateToManyProperty) currentGrailsProp, persistentClass); + collectionBinder.bindCollection((HibernateToManyProperty) currentGrailsProp, collection, persistentClass, mappings, path); + mappings.addCollectionBinding(collection); + value = collection; + } + // work out what type of relationship it is and bind value + else if (currentGrailsProp instanceof org.grails.datastore.mapping.model.types.ManyToOne) { + if (LOG.isDebugEnabled()) + LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as ManyToOne"); + + value = new ManyToOne(metadataBuildingContext, table); + manyToOneBinder.bindManyToOne((Association) currentGrailsProp, (ManyToOne) value, path); + } else if (currentGrailsProp instanceof org.grails.datastore.mapping.model.types.OneToOne association) { + if (LOG.isDebugEnabled()) + LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as OneToOne"); + + if (association.canBindOneToOneWithSingleColumnAndForeignKey()) { + value = new OneToOne(metadataBuildingContext, table, persistentClass); + oneToOneBinder.bindOneToOne((org.grails.datastore.mapping.model.types.OneToOne) currentGrailsProp, (OneToOne) value, path); + } + else { + value = new ManyToOne(metadataBuildingContext, table); + manyToOneBinder.bindManyToOne((Association) currentGrailsProp, (ManyToOne) value, path); + } + } + else if (currentGrailsProp instanceof HibernateEmbeddedProperty embedded) { + value = bindComponent(persistentClass, embedded, mappings); + } + else { + if (LOG.isDebugEnabled()) + LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as SimpleValue"); + + value = new BasicValue(metadataBuildingContext, table); + if (currentGrailsProp.getType().isEnum()) { + String columnName = columnNameForPropertyAndPathFetcher.getColumnNameForPropertyAndPath(currentGrailsProp, path, null); + enumTypeBinder.bindEnumType(currentGrailsProp, currentGrailsProp.getType(), (SimpleValue) value, columnName); + } + else { + // set type + this.simpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, (SimpleValue) value, path); + } + } + componentUpdater.updateComponent(component, componentProperty, currentGrailsProp, value); + return value; + } } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentPropertyBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentPropertyBinder.java deleted file mode 100644 index 52f8222271..0000000000 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentPropertyBinder.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.grails.orm.hibernate.cfg.domainbinding.binder; - -import org.hibernate.boot.spi.InFlightMetadataCollector; -import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.mapping.BasicValue; -import org.hibernate.mapping.Collection; -import org.hibernate.mapping.Component; -import org.hibernate.mapping.ManyToOne; -import org.hibernate.mapping.OneToOne; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.SimpleValue; -import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.grails.datastore.mapping.model.types.Association; -import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty; -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty; -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; -import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder; -import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionType; -import org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher; - -import jakarta.annotation.Nonnull; - -public class ComponentPropertyBinder { - - private static final Logger LOG = LoggerFactory.getLogger(ComponentPropertyBinder.class); - - private final MetadataBuildingContext metadataBuildingContext; - private final CollectionHolder collectionHolder; - private final EnumTypeBinder enumTypeBinder; - private final CollectionBinder collectionBinder; - private final ManyToOneBinder manyToOneBinder; - private final OneToOneBinder oneToOneBinder; - private final ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher; - private final SimpleValueBinder simpleValueBinder; - private final ComponentUpdater componentUpdater; - private ComponentBinder componentBinder; - - public ComponentPropertyBinder(MetadataBuildingContext metadataBuildingContext, - CollectionHolder collectionHolder, - EnumTypeBinder enumTypeBinder, - CollectionBinder collectionBinder, - SimpleValueBinder simpleValueBinder, - OneToOneBinder oneToOneBinder, - ManyToOneBinder manyToOneBinder, - ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher, - ComponentUpdater componentUpdater) { - this.metadataBuildingContext = metadataBuildingContext; - this.collectionHolder = collectionHolder; - this.enumTypeBinder = enumTypeBinder; - this.collectionBinder = collectionBinder; - this.simpleValueBinder = simpleValueBinder; - this.oneToOneBinder = oneToOneBinder; - this.manyToOneBinder = manyToOneBinder; - this.columnNameForPropertyAndPathFetcher = columnNameForPropertyAndPathFetcher; - this.componentUpdater = componentUpdater; - } - - public void setComponentBinder(ComponentBinder componentBinder) { - this.componentBinder = componentBinder; - } - - public Value bindComponentProperty(Component component, - GrailsHibernatePersistentProperty componentProperty, - GrailsHibernatePersistentProperty currentGrailsProp, - PersistentClass persistentClass, - String path, - Table table, - @Nonnull InFlightMetadataCollector mappings) { - Value value; - // see if it's a collection type - CollectionType collectionType = collectionHolder.get(currentGrailsProp.getType()); - if (collectionType != null) { - // create collection - Collection collection = collectionType.create((HibernateToManyProperty) currentGrailsProp, persistentClass); - collectionBinder.bindCollection((HibernateToManyProperty) currentGrailsProp, collection, persistentClass, mappings, path); - mappings.addCollectionBinding(collection); - value = collection; - } - // work out what type of relationship it is and bind value - else if (currentGrailsProp instanceof org.grails.datastore.mapping.model.types.ManyToOne) { - if (LOG.isDebugEnabled()) - LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as ManyToOne"); - - value = new ManyToOne(metadataBuildingContext, table); - manyToOneBinder.bindManyToOne((Association) currentGrailsProp, (ManyToOne) value, path); - } else if (currentGrailsProp instanceof org.grails.datastore.mapping.model.types.OneToOne association) { - if (LOG.isDebugEnabled()) - LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as OneToOne"); - - if (association.canBindOneToOneWithSingleColumnAndForeignKey()) { - value = new OneToOne(metadataBuildingContext, table, persistentClass); - oneToOneBinder.bindOneToOne((org.grails.datastore.mapping.model.types.OneToOne) currentGrailsProp, (OneToOne) value, path); - } - else { - value = new ManyToOne(metadataBuildingContext, table); - manyToOneBinder.bindManyToOne((Association) currentGrailsProp, (ManyToOne) value, path); - } - } - else if (currentGrailsProp instanceof HibernateEmbeddedProperty embedded) { - value = componentBinder.bindComponent(persistentClass, embedded, mappings); - } - else { - if (LOG.isDebugEnabled()) - LOG.debug("[GrailsDomainBinder] Binding property [" + currentGrailsProp.getName() + "] as SimpleValue"); - - value = new BasicValue(metadataBuildingContext, table); - if (currentGrailsProp.getType().isEnum()) { - String columnName = columnNameForPropertyAndPathFetcher.getColumnNameForPropertyAndPath(currentGrailsProp, path, null); - enumTypeBinder.bindEnumType(currentGrailsProp, currentGrailsProp.getType(), (SimpleValue) value, columnName); - } - else { - // set type - this.simpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, (SimpleValue) value, path); - } - } - componentUpdater.updateComponent(component, componentProperty, currentGrailsProp, value); - return value; - } - -} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CompositeIdBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CompositeIdBinder.java index 3dd7d6ae32..90b4e415fb 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CompositeIdBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CompositeIdBinder.java @@ -16,11 +16,11 @@ import jakarta.annotation.Nonnull; public class CompositeIdBinder { private final MetadataBuildingContext metadataBuildingContext; - private final ComponentPropertyBinder componentPropertyBinder; + private final ComponentBinder componentBinder; - public CompositeIdBinder(MetadataBuildingContext metadataBuildingContext, ComponentPropertyBinder componentPropertyBinder) { + public CompositeIdBinder(MetadataBuildingContext metadataBuildingContext, ComponentBinder componentBinder) { this.metadataBuildingContext = metadataBuildingContext; - this.componentPropertyBinder = componentPropertyBinder; + this.componentBinder = componentBinder; } @@ -61,7 +61,7 @@ public class CompositeIdBinder { "] is not a valid property!"); } - componentPropertyBinder.bindComponentProperty(id, identifierProp, property, root, "", root.getTable(), mappings); + componentBinder.bindComponentProperty(id, identifierProp, property, root, "", root.getTable(), mappings); } } } 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 c0628bbae4..455690daf3 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 @@ -35,7 +35,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndP import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator @@ -81,8 +80,9 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec { ) PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator() ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator) - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, + binder.getMappingCacheHolder(), collectionHolder, enumTypeBinderToUse, collectionBinder, @@ -92,8 +92,6 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec { columnNameForPropertyAndPathFetcher, componentUpdater ) - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder) - componentPropertyBinder.setComponentBinder(componentBinder) GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder( metadataBuildingContext, @@ -108,7 +106,7 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec { manyToOneBinder, propertyFromValueCreator ) - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder) + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder) PropertyBinder propertyBinderHelper = new PropertyBinder() SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper) IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder) 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 90d81ffcab..d58eed4f01 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 @@ -20,7 +20,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder @@ -80,8 +79,9 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec { ) PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator() ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator) - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, + binder.getMappingCacheHolder(), collectionHolder, enumTypeBinderToUse, collectionBinder, @@ -91,8 +91,6 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec { columnNameForPropertyAndPathFetcher, componentUpdater ) - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder) - componentPropertyBinder.setComponentBinder(componentBinder) GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder( metadataBuildingContext, @@ -107,7 +105,7 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec { manyToOneBinder, propertyFromValueCreator ) - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder) + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder) PropertyBinder propertyBinderHelper = new PropertyBinder() SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper) IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder) diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentBinderSpec.groovy index 6bee48a1f6..619364cebf 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentBinderSpec.groovy @@ -1,30 +1,95 @@ package org.grails.orm.hibernate.cfg.domainbinding import grails.gorm.specs.HibernateGormDatastoreSpec -import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty +import org.grails.datastore.mapping.model.MappingContext +import org.grails.datastore.mapping.model.PersistentEntity +import org.grails.datastore.mapping.model.PersistentProperty +import org.grails.datastore.mapping.model.types.Association import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity +import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty +import org.grails.orm.hibernate.cfg.Mapping import org.grails.orm.hibernate.cfg.MappingCacheHolder - +import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy +import org.grails.orm.hibernate.cfg.PropertyConfig +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToOneProperty +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOneProperty +import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater +import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder +import org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher +import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder +import org.hibernate.boot.spi.InFlightMetadataCollector +import org.hibernate.mapping.BasicValue import org.hibernate.mapping.Component +import org.hibernate.mapping.ManyToOne as HibernateManyToOne +import org.hibernate.mapping.OneToOne as HibernateOneToOne +import org.hibernate.mapping.Property import org.hibernate.mapping.RootClass +import org.hibernate.mapping.Table +import org.hibernate.mapping.Value import spock.lang.Subject -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder -import org.hibernate.mapping.Value -import org.hibernate.mapping.Table +import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator class ComponentBinderSpec extends HibernateGormDatastoreSpec { + abstract static class TestManyToOne extends HibernateManyToOneProperty { + TestManyToOne(PersistentEntity owner, MappingContext context, java.beans.PropertyDescriptor descriptor) { + super(owner, context, descriptor); + } + } + + abstract static class TestOneToOne extends HibernateOneToOneProperty { + TestOneToOne(PersistentEntity owner, MappingContext context, java.beans.PropertyDescriptor descriptor) { + super(owner, context, descriptor); + } + } + MappingCacheHolder mappingCacheHolder = Mock(MappingCacheHolder) - ComponentPropertyBinder componentPropertyBinder = Mock(ComponentPropertyBinder) + CollectionHolder collectionHolder = new CollectionHolder([:]) + EnumTypeBinder enumTypeBinder = Mock(EnumTypeBinder) + CollectionBinder collectionBinder = Mock(CollectionBinder) + PropertyFromValueCreator propertyFromValueCreator = Mock(PropertyFromValueCreator) + OneToOneBinder oneToOneBinder = Mock(OneToOneBinder) + ManyToOneBinder manyToOneBinder = Mock(ManyToOneBinder) + ColumnNameForPropertyAndPathFetcher columnNameFetcher = Mock(ColumnNameForPropertyAndPathFetcher) + ComponentUpdater componentUpdater + SimpleValueBinder mockSimpleValueBinder = Mock(SimpleValueBinder) @Subject ComponentBinder binder def setup() { - binder = new ComponentBinder(getGrailsDomainBinder().getMetadataBuildingContext(), mappingCacheHolder, componentPropertyBinder) + componentUpdater = new ComponentUpdater(propertyFromValueCreator) + + binder = new ComponentBinder( + getGrailsDomainBinder().getMetadataBuildingContext(), + mappingCacheHolder, + collectionHolder, + enumTypeBinder, + collectionBinder, + mockSimpleValueBinder, + oneToOneBinder, + manyToOneBinder, + columnNameFetcher, + componentUpdater + ) + } + + private void setupProperty(PersistentProperty prop, String name, Mapping mapping, PersistentEntity owner) { + prop.getName() >> name + _ * prop.getOwner() >> owner + if (prop instanceof GrailsHibernatePersistentProperty) { + _ * ((GrailsHibernatePersistentProperty)prop).getHibernateOwner() >> owner + } + def config = new PropertyConfig() + mapping.getColumns().put(name, config) + prop.getMappedForm() >> config } def "should bind component and its properties"() { @@ -60,9 +125,175 @@ class ComponentBinderSpec extends HibernateGormDatastoreSpec { component.getComponentClassName() == Address.name component.getRoleName() == Address.name + ".address" 1 * mappingCacheHolder.cacheMapping(associatedEntity) - 1 * componentPropertyBinder.bindComponentProperty(_ as Component, embeddedProp, prop1, root, "address", _ as Table, mappings) >> Mock(Value) + 1 * mockSimpleValueBinder.bindSimpleValue(prop1, embeddedProp, _ as BasicValue, "address") + } + + def "should bind simple property"() { + given: + def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + def root = new RootClass(metadataBuildingContext) + def component = new Component(metadataBuildingContext, root) + def table = new Table("my_table") + def ownerEntity = Mock(GrailsHibernatePersistentEntity) + ownerEntity.isRoot() >> true + + def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) + + def componentProperty = Mock(GrailsHibernatePersistentProperty) + def mappings = Mock(InFlightMetadataCollector) + def hibernateProperty = new Property() + hibernateProperty.setName("street") + + def mapping = new Mapping() + ownerEntity.getMappedForm() >> mapping + currentGrailsProp.getType() >> String + setupProperty(currentGrailsProp, "street", mapping, ownerEntity) + setupProperty(componentProperty, "address", mapping, ownerEntity) + + when: + binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) + + then: + 1 * mockSimpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, _ as BasicValue, "address") + 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty + } + + def "should bind many-to-one property"() { + given: + def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + def root = new RootClass(metadataBuildingContext) + def component = new Component(metadataBuildingContext, root) + def table = new Table("my_table") + def ownerEntity = Mock(GrailsHibernatePersistentEntity) + ownerEntity.isRoot() >> true + def currentGrailsProp = Mock(TestManyToOne) + def componentProperty = Mock(GrailsHibernatePersistentProperty) + def mappings = Mock(InFlightMetadataCollector) + def hibernateProperty = new Property() + hibernateProperty.setName("owner") + + def mapping = new Mapping() + ownerEntity.getMappedForm() >> mapping + currentGrailsProp.getAssociatedEntity() >> Mock(GrailsHibernatePersistentEntity) { + getName() >> "Owner" + getMappedForm() >> new Mapping() + isRoot() >> true + } + currentGrailsProp.getType() >> Object + setupProperty(currentGrailsProp, "owner", mapping, ownerEntity) + setupProperty(componentProperty, "address", mapping, ownerEntity) + + when: + binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) + + then: + 1 * manyToOneBinder.bindManyToOne(currentGrailsProp, _ as HibernateManyToOne, "address") + 1 * propertyFromValueCreator.createProperty(_ as HibernateManyToOne, currentGrailsProp) >> hibernateProperty + } + + def "should bind one-to-one property"() { + given: + def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + def root = new RootClass(metadataBuildingContext) + def component = new Component(metadataBuildingContext, root) + def table = new Table("my_table") + def ownerEntity = Mock(GrailsHibernatePersistentEntity) + ownerEntity.isRoot() >> true + def currentGrailsProp = Mock(TestOneToOne) + def componentProperty = Mock(GrailsHibernatePersistentProperty) + def mappings = Mock(InFlightMetadataCollector) + def hibernateProperty = new Property() + hibernateProperty.setName("detail") + + def mapping = new Mapping() + ownerEntity.getMappedForm() >> mapping + ((Association)currentGrailsProp).getInverseSide() >> Mock(Association) { + isHasOne() >> false + getOwner() >> Mock(GrailsHibernatePersistentEntity) { + getName() >> "Other" + isRoot() >> true + } + getName() >> "other" + } + currentGrailsProp.getType() >> Object + ((Association)currentGrailsProp).canBindOneToOneWithSingleColumnAndForeignKey() >> true + setupProperty(currentGrailsProp, "detail", mapping, ownerEntity) + setupProperty(componentProperty, "address", mapping, ownerEntity) + + when: + binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) + + then: + 1 * oneToOneBinder.bindOneToOne(currentGrailsProp, _ as HibernateOneToOne, "address") + 1 * propertyFromValueCreator.createProperty(_ as HibernateOneToOne, currentGrailsProp) >> hibernateProperty + } + + def "should bind enum property"() { + given: + def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + def root = new RootClass(metadataBuildingContext) + def component = new Component(metadataBuildingContext, root) + def table = new Table("my_table") + def ownerEntity = Mock(GrailsHibernatePersistentEntity) + ownerEntity.isRoot() >> true + def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) + def componentProperty = Mock(GrailsHibernatePersistentProperty) + def mappings = Mock(InFlightMetadataCollector) + def hibernateProperty = new Property() + hibernateProperty.setName("type") + + def mapping = new Mapping() + ownerEntity.getMappedForm() >> mapping + currentGrailsProp.getType() >> MyEnum + setupProperty(currentGrailsProp, "type", mapping, ownerEntity) + setupProperty(componentProperty, "address", mapping, ownerEntity) + + columnNameFetcher.getColumnNameForPropertyAndPath(currentGrailsProp, "address", null) >> "address_type_col" + + when: + binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) + + then: + 1 * enumTypeBinder.bindEnumType(currentGrailsProp, MyEnum, _ as BasicValue, "address_type_col") + 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty + } + + def "should set columns to nullable when component property is nullable"() { + given: + def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() + def root = new RootClass(metadataBuildingContext) + def component = new Component(metadataBuildingContext, root) + def table = new Table("my_table") + def ownerEntity = Mock(GrailsHibernatePersistentEntity) + ownerEntity.isRoot() >> true + def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) + def componentProperty = Mock(GrailsHibernatePersistentProperty) + def mappings = Mock(InFlightMetadataCollector) + def hibernateProperty = new Property() + hibernateProperty.setName("street") + + def mapping = new Mapping() + ownerEntity.getMappedForm() >> mapping + currentGrailsProp.getType() >> String + setupProperty(currentGrailsProp, "street", mapping, ownerEntity) + setupProperty(componentProperty, "address", mapping, ownerEntity) + + ownerEntity.isComponentPropertyNullable(componentProperty) >> true + + when: + binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) + + then: + 1 * mockSimpleValueBinder.bindSimpleValue( + currentGrailsProp, + componentProperty, + _ as BasicValue, + "address" + ) + 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty } static class MyEntity {} static class Address {} + enum MyEnum { VAL } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentPropertyBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentPropertyBinderSpec.groovy deleted file mode 100644 index 87e522ad36..0000000000 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ComponentPropertyBinderSpec.groovy +++ /dev/null @@ -1,263 +0,0 @@ -package org.grails.orm.hibernate.cfg.domainbinding - -import grails.gorm.specs.HibernateGormDatastoreSpec -import org.grails.datastore.mapping.model.MappingContext -import org.grails.datastore.mapping.model.PersistentEntity -import org.grails.datastore.mapping.model.PersistentProperty -import org.grails.datastore.mapping.model.types.Association -import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity -import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty -import org.grails.orm.hibernate.cfg.Mapping -import org.grails.orm.hibernate.cfg.MappingCacheHolder -import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy -import org.grails.orm.hibernate.cfg.PropertyConfig -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToOneProperty -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOneProperty -import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater -import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder -import org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher -import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolder -import org.hibernate.boot.spi.InFlightMetadataCollector -import org.hibernate.mapping.BasicValue -import org.hibernate.mapping.Component -import org.hibernate.mapping.ManyToOne as HibernateManyToOne -import org.hibernate.mapping.OneToOne as HibernateOneToOne -import org.hibernate.mapping.Property -import org.hibernate.mapping.RootClass -import org.hibernate.mapping.Table -import spock.lang.Subject - -import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator - -class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec { - - abstract static class TestManyToOne extends HibernateManyToOneProperty { - TestManyToOne(PersistentEntity owner, MappingContext context, java.beans.PropertyDescriptor descriptor) { - super(owner, context, descriptor); - } - } - - abstract static class TestOneToOne extends HibernateOneToOneProperty { - TestOneToOne(PersistentEntity owner, MappingContext context, java.beans.PropertyDescriptor descriptor) { - super(owner, context, descriptor); - } - } - - PersistentEntityNamingStrategy namingStrategy = Mock(PersistentEntityNamingStrategy) - MappingCacheHolder mappingCacheHolder = Mock(MappingCacheHolder) - CollectionHolder collectionHolder = new CollectionHolder([:]) - EnumTypeBinder enumTypeBinder = Mock(EnumTypeBinder) - CollectionBinder collectionBinder = Mock(CollectionBinder) - PropertyFromValueCreator propertyFromValueCreator = Mock(PropertyFromValueCreator) - ComponentBinder componentBinder = Mock(ComponentBinder) - OneToOneBinder oneToOneBinder = Mock(OneToOneBinder) - ManyToOneBinder manyToOneBinder = Mock(ManyToOneBinder) - ColumnNameForPropertyAndPathFetcher columnNameFetcher = Mock(ColumnNameForPropertyAndPathFetcher) - ComponentUpdater componentUpdater - - @Subject - ComponentPropertyBinder binder - - def mockSimpleValueBinder = Mock(SimpleValueBinder) // Mock SimpleValueBinder - - def setup() { - componentUpdater = new ComponentUpdater(propertyFromValueCreator) - - binder = new ComponentPropertyBinder( - getGrailsDomainBinder().getMetadataBuildingContext(), - collectionHolder, - enumTypeBinder, - collectionBinder, - mockSimpleValueBinder, - oneToOneBinder, - manyToOneBinder, - columnNameFetcher, - componentUpdater - ) - binder.setComponentBinder(componentBinder) - } - - private void setupProperty(PersistentProperty prop, String name, Mapping mapping, PersistentEntity owner) { - prop.getName() >> name - _ * prop.getOwner() >> owner - if (prop instanceof GrailsHibernatePersistentProperty) { - _ * ((GrailsHibernatePersistentProperty)prop).getHibernateOwner() >> owner - } - def config = new PropertyConfig() - mapping.getColumns().put(name, config) - prop.getMappedForm() >> config - } - - def "should bind simple property"() { - given: - def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() - def root = new RootClass(metadataBuildingContext) - def component = new Component(metadataBuildingContext, root) - def table = new Table("my_table") - def ownerEntity = Mock(GrailsHibernatePersistentEntity) - ownerEntity.isRoot() >> true - - def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) - - def componentProperty = Mock(GrailsHibernatePersistentProperty) - def mappings = Mock(InFlightMetadataCollector) - def hibernateProperty = new Property() - hibernateProperty.setName("street") - - def mapping = new Mapping() - ownerEntity.getMappedForm() >> mapping - currentGrailsProp.getType() >> String - setupProperty(currentGrailsProp, "street", mapping, ownerEntity) - setupProperty(componentProperty, "address", mapping, ownerEntity) - - when: - binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) - - then: - 1 * mockSimpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, _ as BasicValue, "address") - 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty - } - - def "should bind many-to-one property"() { - given: - def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() - def root = new RootClass(metadataBuildingContext) - def component = new Component(metadataBuildingContext, root) - def table = new Table("my_table") - def ownerEntity = Mock(GrailsHibernatePersistentEntity) - ownerEntity.isRoot() >> true - def currentGrailsProp = Mock(TestManyToOne) - def componentProperty = Mock(GrailsHibernatePersistentProperty) - def mappings = Mock(InFlightMetadataCollector) - def hibernateProperty = new Property() - hibernateProperty.setName("owner") - - def mapping = new Mapping() - ownerEntity.getMappedForm() >> mapping - currentGrailsProp.getAssociatedEntity() >> Mock(GrailsHibernatePersistentEntity) { - getName() >> "Owner" - getMappedForm() >> new Mapping() - isRoot() >> true - } - currentGrailsProp.getType() >> Object - setupProperty(currentGrailsProp, "owner", mapping, ownerEntity) - setupProperty(componentProperty, "address", mapping, ownerEntity) - - when: - binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) - - then: - 1 * manyToOneBinder.bindManyToOne(currentGrailsProp, _ as HibernateManyToOne, "address") - 1 * propertyFromValueCreator.createProperty(_ as HibernateManyToOne, currentGrailsProp) >> hibernateProperty - } - - def "should bind one-to-one property"() { - given: - def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() - def root = new RootClass(metadataBuildingContext) - def component = new Component(metadataBuildingContext, root) - def table = new Table("my_table") - def ownerEntity = Mock(GrailsHibernatePersistentEntity) - ownerEntity.isRoot() >> true - def currentGrailsProp = Mock(TestOneToOne) - def componentProperty = Mock(GrailsHibernatePersistentProperty) - def mappings = Mock(InFlightMetadataCollector) - def hibernateProperty = new Property() - hibernateProperty.setName("detail") - - def mapping = new Mapping() - ownerEntity.getMappedForm() >> mapping - ((Association)currentGrailsProp).getInverseSide() >> Mock(Association) { - isHasOne() >> false - getOwner() >> Mock(GrailsHibernatePersistentEntity) { - getName() >> "Other" - isRoot() >> true - } - getName() >> "other" - } - currentGrailsProp.getType() >> Object - ((Association)currentGrailsProp).canBindOneToOneWithSingleColumnAndForeignKey() >> true - setupProperty(currentGrailsProp, "detail", mapping, ownerEntity) - setupProperty(componentProperty, "address", mapping, ownerEntity) - - when: - binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) - - then: - 1 * oneToOneBinder.bindOneToOne(currentGrailsProp, _ as HibernateOneToOne, "address") - 1 * propertyFromValueCreator.createProperty(_ as HibernateOneToOne, currentGrailsProp) >> hibernateProperty - } - - def "should bind enum property"() { - given: - def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() - def root = new RootClass(metadataBuildingContext) - def component = new Component(metadataBuildingContext, root) - def table = new Table("my_table") - def ownerEntity = Mock(GrailsHibernatePersistentEntity) - ownerEntity.isRoot() >> true - def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) - def componentProperty = Mock(GrailsHibernatePersistentProperty) - def mappings = Mock(InFlightMetadataCollector) - def hibernateProperty = new Property() - hibernateProperty.setName("type") - - def mapping = new Mapping() - ownerEntity.getMappedForm() >> mapping - currentGrailsProp.getType() >> MyEnum - setupProperty(currentGrailsProp, "type", mapping, ownerEntity) - setupProperty(componentProperty, "address", mapping, ownerEntity) - - columnNameFetcher.getColumnNameForPropertyAndPath(currentGrailsProp, "address", null) >> "address_type_col" - - when: - binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) - - then: - 1 * enumTypeBinder.bindEnumType(currentGrailsProp, MyEnum, _ as BasicValue, "address_type_col") - 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty - } - - def "should set columns to nullable when component property is nullable"() { - given: - def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() - def root = new RootClass(metadataBuildingContext) - def component = new Component(metadataBuildingContext, root) - def table = new Table("my_table") - def ownerEntity = Mock(GrailsHibernatePersistentEntity) - ownerEntity.isRoot() >> true - def currentGrailsProp = Mock(GrailsHibernatePersistentProperty) - def componentProperty = Mock(GrailsHibernatePersistentProperty) - def mappings = Mock(InFlightMetadataCollector) - def hibernateProperty = new Property() - hibernateProperty.setName("street") - - def mapping = new Mapping() - ownerEntity.getMappedForm() >> mapping - currentGrailsProp.getType() >> String - setupProperty(currentGrailsProp, "street", mapping, ownerEntity) - setupProperty(componentProperty, "address", mapping, ownerEntity) - - ownerEntity.isComponentPropertyNullable(componentProperty) >> true - - when: - binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings) - - then: - 1 * mockSimpleValueBinder.bindSimpleValue( - currentGrailsProp, - componentProperty, - _ as BasicValue, - "address" - ) - 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty - } - - enum MyEnum { VAL } -} diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CompositeIdBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CompositeIdBinderSpec.groovy index 1257776f72..15b580db45 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CompositeIdBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CompositeIdBinderSpec.groovy @@ -11,19 +11,19 @@ import org.hibernate.mapping.RootClass import org.hibernate.mapping.Table import spock.lang.Subject -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder import org.hibernate.mapping.Value class CompositeIdBinderSpec extends HibernateGormDatastoreSpec { - def componentPropertyBinder = Mock(ComponentPropertyBinder) + def componentBinder = Mock(ComponentBinder) @Subject CompositeIdBinder binder def setup() { - binder = new CompositeIdBinder(getGrailsDomainBinder().getMetadataBuildingContext(), componentPropertyBinder) + binder = new CompositeIdBinder(getGrailsDomainBinder().getMetadataBuildingContext(), componentBinder) } def "should bind composite id using property names from CompositeIdentity"() { @@ -54,7 +54,7 @@ class CompositeIdBinderSpec extends HibernateGormDatastoreSpec { root.getIdentifier() instanceof Component root.getIdentifierMapper() instanceof Component root.hasEmbeddedIdentifier() - 2 * componentPropertyBinder.bindComponentProperty(_ as Component, identifierProp, _ as PersistentProperty, root, "", table, mappings) >> Mock(Value) + 2 * componentBinder.bindComponentProperty(_ as Component, identifierProp, _ as PersistentProperty, root, "", table, mappings) >> Mock(Value) } def "should fallback to domainClass composite identity when CompositeIdentity is null"() { @@ -78,7 +78,7 @@ class CompositeIdBinderSpec extends HibernateGormDatastoreSpec { binder.bindCompositeId(domainClass, root, null, mappings) then: - 1 * componentPropertyBinder.bindComponentProperty(_ as Component, identifierProp, prop1, root, "", table, mappings) >> Mock(Value) + 1 * componentBinder.bindComponentProperty(_ as Component, identifierProp, prop1, root, "", table, mappings) >> Mock(Value) } def "should throw MappingException if no composite properties found"() { 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 12933320f6..d672fe8e80 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 @@ -14,7 +14,6 @@ import org.hibernate.mapping.Value import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder @@ -85,23 +84,18 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec { ) PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator() ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator) - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, - namingStrategy, - jdbcEnvironment, binder.getMappingCacheHolder(), collectionHolder, enumTypeBinderToUse, collectionBinder, - propertyFromValueCreator, - null, simpleValueBinder, oneToOneBinder, manyToOneBinder, columnNameForPropertyAndPathFetcher, componentUpdater ) - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater) GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder( metadataBuildingContext, namingStrategy, @@ -115,7 +109,7 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec { manyToOneBinder, propertyFromValueCreator ) - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater) + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder) PropertyBinder propertyBinderHelper = new PropertyBinder() SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper) IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder) @@ -550,4 +544,4 @@ class MapAuthor { class MapBook { Long id String title -} \ No newline at end of file +} 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 33afb724f2..30ab28c01a 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 @@ -20,7 +20,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder @@ -80,8 +79,9 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec { ) PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator() ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator) - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, + binder.getMappingCacheHolder(), collectionHolder, enumTypeBinderToUse, collectionBinder, @@ -91,8 +91,6 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec { columnNameForPropertyAndPathFetcher, componentUpdater ) - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder) - componentPropertyBinder.setComponentBinder(componentBinder) GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder( metadataBuildingContext, @@ -107,7 +105,7 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec { manyToOneBinder, propertyFromValueCreator ) - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder) + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder) PropertyBinder propertyBinderHelper = new PropertyBinder() SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper) IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder) 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 951d1d31c2..8e4f59702a 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 @@ -20,7 +20,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.OneToOneBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater import org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsPropertyBinder @@ -80,8 +79,9 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec { ) PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator() ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator) - ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder( + ComponentBinder componentBinder = new ComponentBinder( metadataBuildingContext, + binder.getMappingCacheHolder(), collectionHolder, enumTypeBinderToUse, collectionBinder, @@ -91,8 +91,6 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec { columnNameForPropertyAndPathFetcher, componentUpdater ) - ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder) - componentPropertyBinder.setComponentBinder(componentBinder) GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder( metadataBuildingContext, @@ -107,7 +105,7 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec { manyToOneBinder, propertyFromValueCreator ) - CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder) + CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentBinder) PropertyBinder propertyBinderHelper = new PropertyBinder() SimpleIdBinder simpleIdBinder = new SimpleIdBinder(metadataBuildingContext, namingStrategy, jdbcEnvironment, new BasicValueIdCreator(jdbcEnvironment), simpleValueBinder, propertyBinderHelper) IdentityBinder identityBinder = new IdentityBinder(simpleIdBinder, compositeIdBinder)
