This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch merge-hibernate6 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 1694d08718c7c03414de11c2eb425a61ae0314b1 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Sun Jul 20 19:55:38 2025 -0500 CollectionForPropertyConfigBinder --- .../orm/hibernate/cfg/GrailsDomainBinder.java | 24 ++----- .../CollectionForPropertyConfigBinder.java | 24 +++++++ .../cfg/domainbinding/EnumTypeBinder.java | 1 - .../CollectionForPropertyConfigBinderSpec.groovy | 79 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 21 deletions(-) diff --git a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java index 9038bfc537..4e518b894f 100644 --- a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java +++ b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java @@ -44,7 +44,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.PersistentPropertyToPropertyCo import org.grails.orm.hibernate.cfg.domainbinding.SimpleValueBinder; import org.grails.orm.hibernate.cfg.domainbinding.StringColumnConstraintsBinder; import org.grails.orm.hibernate.cfg.domainbinding.TypeNameProvider; -import org.grails.orm.hibernate.cfg.domainbinding.UniqueNameGenerator; +import org.grails.orm.hibernate.cfg.domainbinding.*; import org.hibernate.FetchMode; import org.hibernate.MappingException; import org.hibernate.boot.internal.MetadataBuildingContextRootImpl; @@ -487,7 +487,7 @@ public class GrailsDomainBinder implements MetadataContributor { collection.setCollectionTable(associatedClass.getTable()); } - bindCollectionForPropertyConfig(collection, propConfig); + new CollectionForPropertyConfigBinder().bindCollectionForPropertyConfig(collection, propConfig); } final boolean isManyToMany = property instanceof ManyToMany; @@ -545,7 +545,7 @@ public class GrailsDomainBinder implements MetadataContributor { ManyToOne element = new ManyToOne(metadataBuildingContext, collection.getCollectionTable()); bindManyToMany((Association)otherSide, element, mappings, sessionFactoryBeanName); collection.setElement(element); - bindCollectionForPropertyConfig(collection, propConfig); + new CollectionForPropertyConfigBinder().bindCollectionForPropertyConfig(collection, propConfig); if (property.isCircular()) { collection.setInverse(false); } @@ -799,7 +799,7 @@ public class GrailsDomainBinder implements MetadataContributor { collection.setElement(element); - bindCollectionForPropertyConfig(collection, config); + new CollectionForPropertyConfigBinder().bindCollectionForPropertyConfig(collection, config); } private String addUnderscore(String s1, String s2) { @@ -846,22 +846,6 @@ public class GrailsDomainBinder implements MetadataContributor { manyToOne.setReferencedEntityName(property.getAssociatedEntity().getName()); } - private void bindCollectionForPropertyConfig(Collection collection, PropertyConfig config) { - if (config == null) { - collection.setLazy(true); - collection.setExtraLazy(false); - } else { - final FetchMode fetch = config.getFetchMode(); - if(!fetch.equals(FetchMode.JOIN)) { - collection.setLazy(true); - } - final Boolean lazy = config.getLazy(); - if(lazy != null) { - collection.setExtraLazy(lazy); - } - } - } - /** * Binds the primary key value column * diff --git a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinder.java b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinder.java new file mode 100644 index 0000000000..9527fad918 --- /dev/null +++ b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinder.java @@ -0,0 +1,24 @@ +package org.grails.orm.hibernate.cfg.domainbinding; + +import org.grails.orm.hibernate.cfg.PropertyConfig; +import org.hibernate.FetchMode; +import org.hibernate.mapping.Collection; + +public class CollectionForPropertyConfigBinder { + + public void bindCollectionForPropertyConfig(Collection collection, PropertyConfig config) { + if (config == null) { + collection.setLazy(true); + collection.setExtraLazy(false); + } else { + final FetchMode fetch = config.getFetchMode(); + if(!fetch.equals(FetchMode.JOIN)) { + collection.setLazy(true); + } + final Boolean lazy = config.getLazy(); + if(lazy != null) { + collection.setExtraLazy(lazy); + } + } + } +} diff --git a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java index d0357a756d..a076c1fda2 100644 --- a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java +++ b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/EnumTypeBinder.java @@ -40,7 +40,6 @@ public class EnumTypeBinder { private static final Logger LOG = LoggerFactory.getLogger(EnumTypeBinder.class); public void bindEnumType(PersistentProperty property, Class<?> propertyType, SimpleValue simpleValue, String columnName) { - // Create config and mapping objects ONCE and reuse them. PropertyConfig pc = new PersistentPropertyToPropertyConfig().apply(property); final HibernatePersistentEntity owner = (HibernatePersistentEntity) property.getOwner(); Mapping ownerMapping = owner.getMappedForm(); diff --git a/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinderSpec.groovy b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinderSpec.groovy new file mode 100644 index 0000000000..64d04c5d6b --- /dev/null +++ b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionForPropertyConfigBinderSpec.groovy @@ -0,0 +1,79 @@ +package org.grails.orm.hibernate.cfg.domainbinding + +import grails.gorm.specs.HibernateGormDatastoreSpec +import org.grails.orm.hibernate.cfg.PropertyConfig +import org.hibernate.FetchMode +import org.hibernate.mapping.RootClass +import org.hibernate.mapping.Set +import spock.lang.Subject +import spock.lang.Unroll + +class CollectionForPropertyConfigBinderSpec extends HibernateGormDatastoreSpec { + + @Subject + CollectionForPropertyConfigBinder binder = new CollectionForPropertyConfigBinder() + + + + def "should apply default settings when the property config is null"() { + def grailsDomainBinder = getGrailsDomainBinder() + given: "A hibernate collection" + def owner = new RootClass(grailsDomainBinder.metadataBuildingContext) + def collection = new Set(grailsDomainBinder.metadataBuildingContext, owner) + // Set initial state to be different from the expected outcome + collection.setLazy(false) + collection.setExtraLazy(true) + + when: "the binder is called with a null config" + binder.bindCollectionForPropertyConfig(collection, null) + + then: "specific default values are applied" + collection.isLazy() + !collection.isExtraLazy() + } + + @Unroll + def "should bind lazy settings based on fetch mode '#fetchMode.name()'} and an explicit lazy config of #lazySetting"() { + given: "A hibernate collection and a mocked property config" + def owner = new RootClass(grailsDomainBinder.metadataBuildingContext) + def collection = new Set(grailsDomainBinder.metadataBuildingContext, owner) + def config = Mock(PropertyConfig) + + // Set initial state + collection.setLazy(false) + collection.setExtraLazy(false) + + and: "the config is stubbed" + config.getFetchMode() >> fetchMode + config.getLazy() >> lazySetting + + when: "the binder is applied" + binder.bindCollectionForPropertyConfig(collection, config) + + then: "the collection's lazy and extraLazy properties are set according to the binder's logic" + collection.isLazy() == expectedIsLazy + collection.isExtraLazy() == expectedIsExtraLazy + + where: + fetchMode | lazySetting || expectedIsLazy | expectedIsExtraLazy + FetchMode.JOIN | true || false | true + FetchMode.JOIN | false || false | false + FetchMode.JOIN | null || false | false + FetchMode.SELECT | true || true | true + FetchMode.SELECT | false || true | false + FetchMode.SELECT | null || true | false +// FetchMode.SUBSELECT | true || true | true + } + + def "should not throw an exception if the collection itself is null"() { + given: "A valid property config" + def config = Mock(PropertyConfig) + + when: "the binder is called with a null collection" + binder.bindCollectionForPropertyConfig(null, config) + + then: "a NullPointerException is thrown because the code does not guard against it" + thrown(NullPointerException) + } + +} \ No newline at end of file
