You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/02/17 18:42:03 UTC
(grails-core) 04/26: Refactor GORM Hibernate 7 binding logic to centralize component updates
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 97f2ebe89b7fed92525b14377beb9787f5b87d71
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sun Feb 15 22:26:09 2026 -0600
Refactor GORM Hibernate 7 binding logic to centralize component updates
- Create ComponentUpdater to encapsulate shared component-update and nullability logic.
- Refactor ComponentBinder to autonomously create and return Component instances.
- Inject ComponentUpdater into ComponentBinder, ComponentPropertyBinder, and CompositeIdBinder via GrailsDomainBinder.
- Clean up redundant component update calls across binders.
- Update test suite to reflect architectural changes and verify new component update logic.
---
.../orm/hibernate/cfg/GrailsDomainBinder.java | 9 ++-
.../cfg/domainbinding/binder/ComponentBinder.java | 10 ++-
.../binder/ComponentPropertyBinder.java | 33 ++++-----
.../cfg/domainbinding/binder/ComponentUpdater.java | 36 ++++++++++
.../domainbinding/binder/CompositeIdBinder.java | 12 +++-
.../cfg/domainbinding/CollectionBinderSpec.groovy | 9 ++-
.../CollectionSecondPassBinderSpec.groovy | 9 ++-
.../cfg/domainbinding/ComponentBinderSpec.groovy | 9 ++-
.../ComponentPropertyBinderSpec.groovy | 15 ++--
.../cfg/domainbinding/CompositeIdBinderSpec.groovy | 9 ++-
.../domainbinding/GrailsPropertyBinderSpec.groovy | 9 ++-
.../domainbinding/ListSecondPassBinderSpec.groovy | 9 ++-
.../domainbinding/MapSecondPassBinderSpec.groovy | 9 ++-
.../binder/ComponentUpdaterSpec.groovy | 80 ++++++++++++++++++++++
14 files changed, 208 insertions(+), 50 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 fc34c716c7..13c914e79f 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
@@ -19,6 +19,7 @@ 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;
import org.grails.orm.hibernate.cfg.domainbinding.util.NamingStrategyProvider;
@@ -183,6 +184,7 @@ public class GrailsDomainBinder
compositeIdentifierToManyToOneBinder,
simpleValueColumnFetcher
);
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator);
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -196,9 +198,10 @@ public class GrailsDomainBinder
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
);
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, getMappingCacheHolder(), componentPropertyBinder);
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, getMappingCacheHolder(), componentPropertyBinder, componentUpdater);
GrailsPropertyBinder grailsPropertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -212,7 +215,7 @@ public class GrailsDomainBinder
manyToOneBinder,
propertyFromValueCreator
);
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder);
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater);
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 b09fc227fe..0ef76618be 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
@@ -1,10 +1,15 @@
package org.grails.orm.hibernate.cfg.domainbinding.binder;
+import java.util.Iterator;
+
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
+import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
+import org.hibernate.mapping.Value;
import org.grails.datastore.mapping.model.config.GormProperties;
import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity;
@@ -12,6 +17,7 @@ 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.util.PropertyFromValueCreator;
import jakarta.annotation.Nonnull;
@@ -20,11 +26,13 @@ public class ComponentBinder {
private final MetadataBuildingContext metadataBuildingContext;
private final MappingCacheHolder mappingCacheHolder;
private final ComponentPropertyBinder componentPropertyBinder;
+ private final ComponentUpdater componentUpdater;
- public ComponentBinder(MetadataBuildingContext metadataBuildingContext, MappingCacheHolder mappingCacheHolder, ComponentPropertyBinder componentPropertyBinder) {
+ public ComponentBinder(MetadataBuildingContext metadataBuildingContext, MappingCacheHolder mappingCacheHolder, ComponentPropertyBinder componentPropertyBinder, ComponentUpdater componentUpdater) {
this.metadataBuildingContext = metadataBuildingContext;
this.mappingCacheHolder = mappingCacheHolder;
this.componentPropertyBinder = componentPropertyBinder;
+ this.componentUpdater = componentUpdater;
}
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
index 697b99179c..75a25f3118 100644
--- 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
@@ -52,6 +52,7 @@ public class ComponentPropertyBinder {
private final ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher;
private final SimpleValueBinder simpleValueBinder;
private final ComponentBinder componentBinder;
+ private final ComponentUpdater componentUpdater;
public ComponentPropertyBinder(MetadataBuildingContext metadataBuildingContext,
PersistentEntityNamingStrategy namingStrategy,
@@ -66,7 +67,8 @@ public class ComponentPropertyBinder {
new SimpleValueBinder(namingStrategy, jdbcEnvironment),
new OneToOneBinder(namingStrategy, jdbcEnvironment),
new ManyToOneBinder(namingStrategy, jdbcEnvironment),
- new ColumnNameForPropertyAndPathFetcher(namingStrategy, new DefaultColumnNameFetcher(namingStrategy), new BackticksRemover()));
+ new ColumnNameForPropertyAndPathFetcher(namingStrategy, new DefaultColumnNameFetcher(namingStrategy), new BackticksRemover()),
+ new ComponentUpdater(propertyFromValueCreator));
}
public ComponentPropertyBinder(MetadataBuildingContext metadataBuildingContext,
@@ -81,7 +83,8 @@ public class ComponentPropertyBinder {
SimpleValueBinder simpleValueBinder,
OneToOneBinder oneToOneBinder,
ManyToOneBinder manyToOneBinder,
- ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher) {
+ ColumnNameForPropertyAndPathFetcher columnNameForPropertyAndPathFetcher,
+ ComponentUpdater componentUpdater) {
this.metadataBuildingContext = metadataBuildingContext;
this.namingStrategy = namingStrategy;
this.jdbcEnvironment = jdbcEnvironment;
@@ -90,22 +93,23 @@ public class ComponentPropertyBinder {
this.enumTypeBinder = enumTypeBinder;
this.collectionBinder = collectionBinder;
this.propertyFromValueCreator = propertyFromValueCreator;
- this.componentBinder = componentBinder != null ? componentBinder : new ComponentBinder(metadataBuildingContext, mappingCacheHolder, this);
+ this.componentBinder = componentBinder != null ? componentBinder : new ComponentBinder(metadataBuildingContext, mappingCacheHolder, this, componentUpdater);
this.simpleValueBinder = simpleValueBinder;
this.oneToOneBinder = oneToOneBinder;
this.manyToOneBinder = manyToOneBinder;
this.columnNameForPropertyAndPathFetcher = columnNameForPropertyAndPathFetcher;
+ this.componentUpdater = componentUpdater;
}
- public void bindComponentProperty(Component component,
- GrailsHibernatePersistentProperty componentProperty,
+ public Value bindComponentProperty(Component component,
+ GrailsHibernatePersistentProperty componentProperty,
GrailsHibernatePersistentProperty currentGrailsProp,
- PersistentClass persistentClass,
+ PersistentClass persistentClass,
String path,
- Table table,
- @Nonnull InFlightMetadataCollector mappings) {
+ Table table,
+ @Nonnull InFlightMetadataCollector mappings) {
Value value;
// see if it's a collection type
CollectionType collectionType = collectionHolder.get(currentGrailsProp.getType());
@@ -153,17 +157,8 @@ public class ComponentPropertyBinder {
this.simpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, (SimpleValue) value, path);
}
}
-
- Property persistentProperty = propertyFromValueCreator.createProperty(value, currentGrailsProp);
- component.addProperty(persistentProperty);
- if (componentProperty != null && componentProperty.getOwner() instanceof GrailsHibernatePersistentEntity ghpe && ghpe.isComponentPropertyNullable(componentProperty)) {
- final Iterator<?> columnIterator = value.getColumns().iterator();
- while (columnIterator.hasNext()) {
- Column c = (Column) columnIterator.next();
- c.setNullable(true);
- }
- }
+ 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/ComponentUpdater.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentUpdater.java
new file mode 100644
index 0000000000..8d25a0842d
--- /dev/null
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentUpdater.java
@@ -0,0 +1,36 @@
+package org.grails.orm.hibernate.cfg.domainbinding.binder;
+
+import java.util.Iterator;
+
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Value;
+
+import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity;
+import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty;
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator;
+
+public class ComponentUpdater {
+
+ private final PropertyFromValueCreator propertyFromValueCreator;
+
+ public ComponentUpdater(PropertyFromValueCreator propertyFromValueCreator) {
+ this.propertyFromValueCreator = propertyFromValueCreator;
+ }
+
+ public void updateComponent(Component component,
+ GrailsHibernatePersistentProperty componentProperty,
+ GrailsHibernatePersistentProperty currentGrailsProp,
+ Value value) {
+ Property persistentProperty = propertyFromValueCreator.createProperty(value, currentGrailsProp);
+ component.addProperty(persistentProperty);
+ if (componentProperty != null && componentProperty.getOwner() instanceof GrailsHibernatePersistentEntity ghpe && ghpe.isComponentPropertyNullable(componentProperty)) {
+ final Iterator<?> columnIterator = value.getColumns().iterator();
+ while (columnIterator.hasNext()) {
+ Column c = (Column) columnIterator.next();
+ c.setNullable(true);
+ }
+ }
+ }
+}
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 048715a1ad..3426fe5440 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
@@ -1,15 +1,21 @@
package org.grails.orm.hibernate.cfg.domainbinding.binder;
+import java.util.Iterator;
+
import org.hibernate.MappingException;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
+import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.Value;
import org.grails.orm.hibernate.cfg.CompositeIdentity;
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.domainbinding.util.PropertyFromValueCreator;
import jakarta.annotation.Nonnull;
@@ -17,10 +23,12 @@ public class CompositeIdBinder {
private final MetadataBuildingContext metadataBuildingContext;
private final ComponentPropertyBinder componentPropertyBinder;
+ private final ComponentUpdater componentUpdater;
- public CompositeIdBinder(MetadataBuildingContext metadataBuildingContext, ComponentPropertyBinder componentPropertyBinder) {
+ public CompositeIdBinder(MetadataBuildingContext metadataBuildingContext, ComponentPropertyBinder componentPropertyBinder, ComponentUpdater componentUpdater) {
this.metadataBuildingContext = metadataBuildingContext;
this.componentPropertyBinder = componentPropertyBinder;
+ this.componentUpdater = componentUpdater;
}
@@ -61,7 +69,7 @@ public class CompositeIdBinder {
"] is not a valid property!");
}
- componentPropertyBinder.bindComponentProperty(id, identifierProp, property, root, "", root.getTable(), mappings);
+ componentPropertyBinder.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 2653cfd25a..cb1f99cfcb 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
@@ -36,6 +36,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionHolde
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
import org.grails.orm.hibernate.cfg.domainbinding.binder.ClassPropertiesBinder
@@ -79,6 +80,7 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec {
simpleValueColumnFetcher
)
PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator()
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator)
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -92,9 +94,10 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec {
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
)
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder)
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater)
GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -108,7 +111,7 @@ class CollectionBinderSpec extends HibernateGormDatastoreSpec {
manyToOneBinder,
propertyFromValueCreator
)
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater)
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 19e5e00eee..d9b5356afe 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
@@ -29,6 +29,7 @@ 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
import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
@@ -81,6 +82,7 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueColumnFetcher
)
PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator()
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator)
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -94,9 +96,10 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
)
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder)
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater)
GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -110,7 +113,7 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec {
manyToOneBinder,
propertyFromValueCreator
)
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater)
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 dd8d19890f..a35d653d04 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
@@ -12,17 +12,21 @@ import spock.lang.Subject
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.hibernate.mapping.Value
+import org.hibernate.mapping.Table
class ComponentBinderSpec extends HibernateGormDatastoreSpec {
MappingCacheHolder mappingCacheHolder = Mock(MappingCacheHolder)
ComponentPropertyBinder componentPropertyBinder = Mock(ComponentPropertyBinder)
+ ComponentUpdater componentUpdater = Mock(ComponentUpdater)
@Subject
ComponentBinder binder
def setup() {
- binder = new ComponentBinder(getGrailsDomainBinder().getMetadataBuildingContext(), mappingCacheHolder, componentPropertyBinder)
+ binder = new ComponentBinder(getGrailsDomainBinder().getMetadataBuildingContext(), mappingCacheHolder, componentPropertyBinder, componentUpdater)
}
def "should bind component and its properties"() {
@@ -30,6 +34,7 @@ class ComponentBinderSpec extends HibernateGormDatastoreSpec {
def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext()
def root = new RootClass(metadataBuildingContext)
root.setEntityName("MyEntity")
+ root.setTable(new Table("my_entity"))
def embeddedProp = GroovyMock(HibernateEmbeddedProperty)
def associatedEntity = GroovyMock(GrailsHibernatePersistentEntity)
@@ -57,7 +62,7 @@ class ComponentBinderSpec extends HibernateGormDatastoreSpec {
component.getComponentClassName() == Address.name
component.getRoleName() == Address.name + ".address"
1 * mappingCacheHolder.cacheMapping(associatedEntity)
- 1 * componentPropertyBinder.bindComponentProperty(_, _, _, _, _, _, _)
+ 1 * componentPropertyBinder.bindComponentProperty(_ as Component, embeddedProp, prop1, root, "address", _ as Table, mappings) >> Mock(Value)
}
static class MyEntity {}
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
index 0a4df79439..8ed981ff28 100644
--- 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
@@ -16,6 +16,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOnePro
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
@@ -58,6 +59,7 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
OneToOneBinder oneToOneBinder = Mock(OneToOneBinder)
ManyToOneBinder manyToOneBinder = Mock(ManyToOneBinder)
ColumnNameForPropertyAndPathFetcher columnNameFetcher = Mock(ColumnNameForPropertyAndPathFetcher)
+ ComponentUpdater componentUpdater
@Subject
ComponentPropertyBinder binder
@@ -66,6 +68,7 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
def setup() {
def jdbcEnvironment = Mock(org.hibernate.engine.jdbc.env.spi.JdbcEnvironment)
+ componentUpdater = new ComponentUpdater(propertyFromValueCreator)
binder = new ComponentPropertyBinder(
getGrailsDomainBinder().getMetadataBuildingContext(),
@@ -80,7 +83,8 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
mockSimpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameFetcher
+ columnNameFetcher,
+ componentUpdater
)
}
@@ -124,7 +128,7 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
then:
1 * mockSimpleValueBinder.bindSimpleValue(currentGrailsProp, componentProperty, _ as BasicValue, "address")
- component.getProperty("street") == hibernateProperty
+ 1 * propertyFromValueCreator.createProperty(_ as BasicValue, currentGrailsProp) >> hibernateProperty
}
def "should bind many-to-one property"() {
@@ -158,8 +162,8 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings)
then:
+ 1 * manyToOneBinder.bindManyToOne(currentGrailsProp, _ as HibernateManyToOne, "address")
1 * propertyFromValueCreator.createProperty(_ as HibernateManyToOne, currentGrailsProp) >> hibernateProperty
- component.getProperty("owner") == hibernateProperty
}
def "should bind one-to-one property"() {
@@ -197,8 +201,8 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
binder.bindComponentProperty(component, componentProperty, currentGrailsProp, root, "address", table, mappings)
then:
+ 1 * oneToOneBinder.bindOneToOne(currentGrailsProp, _ as HibernateOneToOne, "address")
1 * propertyFromValueCreator.createProperty(_ as HibernateOneToOne, currentGrailsProp) >> hibernateProperty
- component.getProperty("detail") == hibernateProperty
}
def "should bind enum property"() {
@@ -231,6 +235,7 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
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"() {
@@ -267,7 +272,7 @@ class ComponentPropertyBinderSpec extends HibernateGormDatastoreSpec {
_ as BasicValue,
"address"
)
- 1 * ownerEntity.isComponentPropertyNullable(componentProperty) >> true
+ 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 cc66523f39..b6936d735e 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
@@ -13,16 +13,19 @@ import spock.lang.Subject
import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentPropertyBinder
import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder
+import org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentUpdater
+import org.hibernate.mapping.Value
class CompositeIdBinderSpec extends HibernateGormDatastoreSpec {
def componentPropertyBinder = Mock(ComponentPropertyBinder)
+ def componentUpdater = Mock(ComponentUpdater)
@Subject
CompositeIdBinder binder
def setup() {
- binder = new CompositeIdBinder(getGrailsDomainBinder().getMetadataBuildingContext(), componentPropertyBinder)
+ binder = new CompositeIdBinder(getGrailsDomainBinder().getMetadataBuildingContext(), componentPropertyBinder, componentUpdater)
}
def "should bind composite id using property names from CompositeIdentity"() {
@@ -53,7 +56,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)
+ 2 * componentPropertyBinder.bindComponentProperty(_ as Component, identifierProp, _ as PersistentProperty, root, "", table, mappings) >> Mock(Value)
}
def "should fallback to domainClass composite identity when CompositeIdentity is null"() {
@@ -77,7 +80,7 @@ class CompositeIdBinderSpec extends HibernateGormDatastoreSpec {
binder.bindCompositeId(domainClass, root, null, mappings)
then:
- 1 * componentPropertyBinder.bindComponentProperty(_ as Component, identifierProp, prop1, root, "", table, mappings)
+ 1 * componentPropertyBinder.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 e6855682cb..12933320f6 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
@@ -15,6 +15,7 @@ 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
import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneBinder
@@ -83,6 +84,7 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
simpleValueColumnFetcher
)
PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator()
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator)
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -96,9 +98,10 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
)
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder)
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater)
GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -112,7 +115,7 @@ class GrailsPropertyBinderSpec extends HibernateGormDatastoreSpec {
manyToOneBinder,
propertyFromValueCreator
)
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater)
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/ListSecondPassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ListSecondPassBinderSpec.groovy
index 3dfcbbcb13..36fe049ac2 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
@@ -31,6 +31,7 @@ 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
import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
@@ -83,6 +84,7 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueColumnFetcher
)
PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator()
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator)
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -96,9 +98,10 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
)
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder)
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater)
GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -112,7 +115,7 @@ class ListSecondPassBinderSpec extends HibernateGormDatastoreSpec {
manyToOneBinder,
propertyFromValueCreator
)
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater)
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 adbb5f0e93..44736dc535 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
@@ -31,6 +31,7 @@ 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
import org.grails.orm.hibernate.cfg.domainbinding.binder.IdentityBinder
@@ -83,6 +84,7 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueColumnFetcher
)
PropertyFromValueCreator propertyFromValueCreator = new PropertyFromValueCreator()
+ ComponentUpdater componentUpdater = new ComponentUpdater(propertyFromValueCreator)
ComponentPropertyBinder componentPropertyBinder = new ComponentPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -96,9 +98,10 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec {
simpleValueBinder,
oneToOneBinder,
manyToOneBinder,
- columnNameForPropertyAndPathFetcher
+ columnNameForPropertyAndPathFetcher,
+ componentUpdater
)
- ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder)
+ ComponentBinder componentBinder = new ComponentBinder(metadataBuildingContext, binder.getMappingCacheHolder(), componentPropertyBinder, componentUpdater)
GrailsPropertyBinder propertyBinder = new GrailsPropertyBinder(
metadataBuildingContext,
namingStrategy,
@@ -112,7 +115,7 @@ class MapSecondPassBinderSpec extends HibernateGormDatastoreSpec {
manyToOneBinder,
propertyFromValueCreator
)
- CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder)
+ CompositeIdBinder compositeIdBinder = new CompositeIdBinder(metadataBuildingContext, componentPropertyBinder, componentUpdater)
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/binder/ComponentUpdaterSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentUpdaterSpec.groovy
new file mode 100644
index 0000000000..1a940b8fba
--- /dev/null
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ComponentUpdaterSpec.groovy
@@ -0,0 +1,80 @@
+package org.grails.orm.hibernate.cfg.domainbinding.binder
+
+import grails.gorm.specs.HibernateGormDatastoreSpec
+import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentEntity
+import org.grails.orm.hibernate.cfg.GrailsHibernatePersistentProperty
+import org.grails.orm.hibernate.cfg.domainbinding.util.PropertyFromValueCreator
+import org.hibernate.mapping.BasicValue
+import org.hibernate.mapping.Column
+import org.hibernate.mapping.Component
+import org.hibernate.mapping.Property
+import org.hibernate.mapping.RootClass
+import spock.lang.Subject
+
+class ComponentUpdaterSpec extends HibernateGormDatastoreSpec {
+
+ def propertyFromValueCreator = Mock(PropertyFromValueCreator)
+
+ @Subject
+ ComponentUpdater updater
+
+ def setup() {
+ updater = new ComponentUpdater(propertyFromValueCreator)
+ }
+
+ def "should add property to component and set columns nullable if component property is nullable"() {
+ given:
+ def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext()
+ def root = new RootClass(metadataBuildingContext)
+ def component = new Component(metadataBuildingContext, root)
+
+ def componentProperty = Mock(GrailsHibernatePersistentProperty)
+ def currentGrailsProp = Mock(GrailsHibernatePersistentProperty)
+ def value = new BasicValue(metadataBuildingContext, root.getTable())
+ def column = new Column("test_col")
+ value.addColumn(column)
+
+ def hibernateProperty = new Property()
+ hibernateProperty.setName("testProp")
+
+ def ownerEntity = Mock(GrailsHibernatePersistentEntity)
+ componentProperty.getOwner() >> ownerEntity
+ ownerEntity.isComponentPropertyNullable(componentProperty) >> true
+
+ when:
+ updater.updateComponent(component, componentProperty, currentGrailsProp, value)
+
+ then:
+ 1 * propertyFromValueCreator.createProperty(value, currentGrailsProp) >> hibernateProperty
+ component.getProperty("testProp") == hibernateProperty
+ column.isNullable()
+ }
+
+ def "should not set columns nullable if component property is not nullable"() {
+ given:
+ def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext()
+ def root = new RootClass(metadataBuildingContext)
+ def component = new Component(metadataBuildingContext, root)
+
+ def componentProperty = Mock(GrailsHibernatePersistentProperty)
+ def currentGrailsProp = Mock(GrailsHibernatePersistentProperty)
+ def value = new BasicValue(metadataBuildingContext, root.getTable())
+ def column = new Column("test_col")
+ column.setNullable(false)
+ value.addColumn(column)
+
+ def hibernateProperty = new Property()
+ hibernateProperty.setName("testProp")
+
+ def ownerEntity = Mock(GrailsHibernatePersistentEntity)
+ componentProperty.getOwner() >> ownerEntity
+ ownerEntity.isComponentPropertyNullable(componentProperty) >> false
+
+ when:
+ updater.updateComponent(component, componentProperty, currentGrailsProp, value)
+
+ then:
+ 1 * propertyFromValueCreator.createProperty(value, currentGrailsProp) >> hibernateProperty
+ !column.isNullable()
+ }
+}