This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 8.0.x-hibernate7-dev in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 1b0d7a5b38327206ff0fbe0901bd1f1fceb5a733 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Tue Mar 3 12:22:12 2026 -0600 refactor: move DependantValue creation into CollectionKeyBinder --- .../cfg/domainbinding/binder/CollectionBinder.java | 4 +- .../secondpass/CollectionKeyBinder.java | 13 ++++-- .../secondpass/CollectionKeyColumnUpdater.java | 2 +- .../secondpass/CollectionSecondPassBinder.java | 11 +---- .../secondpass/CollectionKeyBinderSpec.groovy | 53 ++++++++++++---------- .../CollectionSecondPassBinderSpec.groovy | 2 +- 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CollectionBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CollectionBinder.java index 2a9fa23bcc..7749b30556 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CollectionBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/CollectionBinder.java @@ -110,7 +110,6 @@ public class CollectionBinder { new ColumnConfigToColumnBinder()); this.collectionSecondPassBinder = new CollectionSecondPassBinder( - new PrimaryKeyValueCreator(metadataBuildingContext), new CollectionKeyColumnUpdater(), new UnidirectionalOneToManyBinder(collectionWithJoinTableBinder, mappings), collectionWithJoinTableBinder, @@ -118,7 +117,8 @@ public class CollectionBinder { new CollectionKeyBinder( new BidirectionalOneToManyLinker(grailsPropertyResolver), new DependentKeyValueBinder(simpleValueBinder, compositeIdentifierToManyToOneBinder), - simpleValueColumnBinder), + simpleValueColumnBinder, + new PrimaryKeyValueCreator(metadataBuildingContext)), new BidirectionalMapElementBinder(manyToOneBinder, collectionForPropertyConfigBinder), new ManyToManyElementBinder(manyToOneBinder, collectionForPropertyConfigBinder), new CollectionOrderByBinder(), diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinder.java index 49d74fa661..36afedd005 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinder.java @@ -33,23 +33,27 @@ public class CollectionKeyBinder { private final BidirectionalOneToManyLinker bidirectionalOneToManyLinker; private final DependentKeyValueBinder dependentKeyValueBinder; private final SimpleValueColumnBinder simpleValueColumnBinder; + private final PrimaryKeyValueCreator primaryKeyValueCreator; /** Creates a new {@link CollectionKeyBinder} instance. */ public CollectionKeyBinder( BidirectionalOneToManyLinker bidirectionalOneToManyLinker, DependentKeyValueBinder dependentKeyValueBinder, - SimpleValueColumnBinder simpleValueColumnBinder) { + SimpleValueColumnBinder simpleValueColumnBinder, + PrimaryKeyValueCreator primaryKeyValueCreator) { this.bidirectionalOneToManyLinker = bidirectionalOneToManyLinker; this.dependentKeyValueBinder = dependentKeyValueBinder; this.simpleValueColumnBinder = simpleValueColumnBinder; + this.primaryKeyValueCreator = primaryKeyValueCreator; } - /** Binds the collection key for the given property and collection. */ - public void bind( + /** Creates the {@link DependantValue} key, sets it on the collection, and binds it. */ + public DependantValue bind( HibernateToManyProperty property, - DependantValue key, PersistentClass associatedClass, Collection collection) { + DependantValue key = primaryKeyValueCreator.createPrimaryKeyValue(collection); + collection.setKey(key); if (property.isBidirectional()) { var inverseSide = property.getHibernateInverseSide(); if (inverseSide instanceof ToOne && property.shouldBindWithForeignKey()) { @@ -66,5 +70,6 @@ public class CollectionKeyBinder { dependentKeyValueBinder.bind(property, key); } } + return key; } } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyColumnUpdater.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyColumnUpdater.java index 3f8464438d..0d9f2f55e3 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyColumnUpdater.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyColumnUpdater.java @@ -28,7 +28,7 @@ public class CollectionKeyColumnUpdater { /** Force nullable and check updatable. */ public void forceNullableAndCheckUpdatable(DependantValue key, HibernateToManyProperty property) { - StreamSupport.stream(key.getColumns().spliterator(), false) + key.getColumns().stream() .filter(Objects::nonNull) .forEach(column -> column.setNullable(true)); diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java index 501f49d55b..6ee0f04118 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java @@ -38,7 +38,6 @@ public class CollectionSecondPassBinder { private final CollectionKeyBinder collectionKeyBinder; private final BidirectionalMapElementBinder bidirectionalMapElementBinder; private final ManyToManyElementBinder manyToManyElementBinder; - private final PrimaryKeyValueCreator primaryKeyValueCreator; private final CollectionKeyColumnUpdater collectionKeyColumnUpdater; private final UnidirectionalOneToManyBinder unidirectionalOneToManyBinder; private final CollectionWithJoinTableBinder collectionWithJoinTableBinder; @@ -46,7 +45,6 @@ public class CollectionSecondPassBinder { /** Creates a new {@link CollectionSecondPassBinder} instance. */ public CollectionSecondPassBinder( - PrimaryKeyValueCreator primaryKeyValueCreator, CollectionKeyColumnUpdater collectionKeyColumnUpdater, UnidirectionalOneToManyBinder unidirectionalOneToManyBinder, CollectionWithJoinTableBinder collectionWithJoinTableBinder, @@ -56,7 +54,6 @@ public class CollectionSecondPassBinder { ManyToManyElementBinder manyToManyElementBinder, CollectionOrderByBinder collectionOrderByBinder, CollectionMultiTenantFilterBinder collectionMultiTenantFilterBinder) { - this.primaryKeyValueCreator = primaryKeyValueCreator; this.collectionKeyColumnUpdater = collectionKeyColumnUpdater; this.unidirectionalOneToManyBinder = unidirectionalOneToManyBinder; this.collectionWithJoinTableBinder = collectionWithJoinTableBinder; @@ -80,13 +77,9 @@ public class CollectionSecondPassBinder { bindOneToManyAssociation(property, associatedClass, collection); collectionMultiTenantFilterBinder.bind(property, collection); - if (property.isSorted()) { - collection.setSorted(true); - } + collection.setSorted(property.isSorted()); - DependantValue key = primaryKeyValueCreator.createPrimaryKeyValue(collection); - collection.setKey(key); - collectionKeyBinder.bind(property, key, associatedClass, collection); + DependantValue key = collectionKeyBinder.bind(property, associatedClass, collection); Optional.ofNullable(property.getMappedForm().getCache()) .ifPresent(cacheConfig -> collection.setCacheConcurrencyStrategy(cacheConfig.getUsage())); diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinderSpec.groovy index 12d2881e03..9b4332cb2f 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionKeyBinderSpec.groovy @@ -3,7 +3,6 @@ package org.grails.orm.hibernate.cfg.domainbinding.secondpass import grails.gorm.annotation.Entity import grails.gorm.specs.HibernateGormDatastoreSpec import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ManyToOneValuesBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity @@ -12,7 +11,6 @@ import org.grails.orm.hibernate.cfg.domainbinding.util.GrailsPropertyResolver import org.hibernate.mapping.Bag import org.hibernate.mapping.BasicValue import org.hibernate.mapping.Column -import org.hibernate.mapping.DependantValue import org.hibernate.mapping.Property import org.hibernate.mapping.RootClass import org.hibernate.mapping.Table @@ -46,7 +44,8 @@ class CollectionKeyBinderSpec extends HibernateGormDatastoreSpec { def botml = new BidirectionalOneToManyLinker(new GrailsPropertyResolver()) def dkvb = new DependentKeyValueBinder(svb, citmto) def svcb = new SimpleValueColumnBinder() - binder = new CollectionKeyBinder(botml, dkvb, svcb) + def pkvc = new PrimaryKeyValueCreator(mbc) + binder = new CollectionKeyBinder(botml, dkvb, svcb, pkvc) } private HibernateToManyProperty propertyFor(Class ownerClass, String name = "items") { @@ -68,71 +67,79 @@ class CollectionKeyBinderSpec extends HibernateGormDatastoreSpec { return rootClass } - private DependantValue keyWithTable(String tableName = "test_table") { + private RootClass ownerRootClass(String tableName) { def mbc = getGrailsDomainBinder().getMetadataBuildingContext() + def rootClass = new RootClass(mbc) def table = new Table("test", tableName) - def wrapped = new BasicValue(mbc, table) - return new DependantValue(mbc, table, wrapped) + rootClass.setTable(table) + def idValue = new BasicValue(mbc, table) + idValue.setTypeName("long") + idValue.addColumn(new Column("id")) + rootClass.setIdentifier(idValue) + return rootClass + } + + private Bag bagWithOwner(RootClass owner, String collectionTableName) { + def mbc = getGrailsDomainBinder().getMetadataBuildingContext() + def bag = new Bag(mbc, owner) + bag.setCollectionTable(new Table("test", collectionTableName)) + return bag } def "bind sets collection inverse for bidirectional one-to-many with foreign key"() { given: def property = propertyFor(CKBBidOwner) def associatedClass = rootClassWith(CKBBidItem.name, "owner", "OWNER_ID") - def key = keyWithTable("ckb_bid_item") - def collection = new Bag(getGrailsDomainBinder().getMetadataBuildingContext(), null) + def collection = bagWithOwner(ownerRootClass("ckb_bid_owner"), "ckb_bid_item") when: - binder.bind(property, key, associatedClass, collection) + binder.bind(property, associatedClass, collection) then: collection.isInverse() - key.getColumnSpan() > 0 + collection.getKey().getColumnSpan() > 0 } def "bind delegates to dependentKeyValueBinder for bidirectional many-to-many"() { given: def property = propertyFor(CKBManyToManyOwner) - def key = new DependantValue(getGrailsDomainBinder().getMetadataBuildingContext(), null, null) def associatedClass = new RootClass(getGrailsDomainBinder().getMetadataBuildingContext()) - def collection = new Bag(getGrailsDomainBinder().getMetadataBuildingContext(), null) + def collection = bagWithOwner(ownerRootClass("ckb_mtm_owner"), "ckb_mtm_join") when: - binder.bind(property, key, associatedClass, collection) + binder.bind(property, associatedClass, collection) then: - key.getColumnSpan() > 0 + collection.getKey().getColumnSpan() > 0 !collection.isInverse() } def "bind uses simpleValueColumnBinder for unidirectional with join key mapping"() { given: def property = propertyFor(CKBJoinKeyOwner) - def key = keyWithTable("ckb_join_key_owner_ckb_join_key_item") def associatedClass = new RootClass(getGrailsDomainBinder().getMetadataBuildingContext()) - def collection = new Bag(getGrailsDomainBinder().getMetadataBuildingContext(), null) + def collection = bagWithOwner(ownerRootClass("ckb_join_key_owner"), "ckb_join_key_owner_ckb_join_key_item") when: - binder.bind(property, key, associatedClass, collection) + binder.bind(property, associatedClass, collection) then: - key.getTypeName() == "long" - key.getColumnSpan() > 0 + collection.getKey().getTypeName() == "long" + collection.getKey().getColumnSpan() > 0 !collection.isInverse() } def "bind delegates to dependentKeyValueBinder for unidirectional without join key mapping"() { given: def property = propertyFor(CKBUniOwner) - def key = new DependantValue(getGrailsDomainBinder().getMetadataBuildingContext(), null, null) def associatedClass = new RootClass(getGrailsDomainBinder().getMetadataBuildingContext()) - def collection = new Bag(getGrailsDomainBinder().getMetadataBuildingContext(), null) + def collection = bagWithOwner(ownerRootClass("ckb_uni_owner"), "ckb_uni_owner_ckb_uni_item") when: - binder.bind(property, key, associatedClass, collection) + binder.bind(property, associatedClass, collection) then: - key.getColumnSpan() > 0 + collection.getKey().getColumnSpan() > 0 !collection.isInverse() } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinderSpec.groovy index 4aa8190304..46a18eba1c 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinderSpec.groovy @@ -41,7 +41,7 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec { def dcnf = new DefaultColumnNameFetcher(ns, new BackticksRemover()) def svcb = new SimpleValueColumnBinder() - binder = new CollectionSecondPassBinder(pkvc, cku, uotmb, cwjtb, cfpcb, new CollectionKeyBinder(botml, dkvb, svcb), new BidirectionalMapElementBinder(mtob, cfpcb), new ManyToManyElementBinder(mtob, cfpcb), new CollectionOrderByBinder(), new CollectionMultiTenantFilterBinder(dcnf)) + binder = new CollectionSecondPassBinder(cku, uotmb, cwjtb, cfpcb, new CollectionKeyBinder(botml, dkvb, svcb, pkvc), new BidirectionalMapElementBinder(mtob, cfpcb), new ManyToManyElementBinder(mtob, cfpcb), new CollectionOrderByBinder(), new CollectionMultiTenantFilterBinder(dcnf)) } protected HibernatePersistentProperty createTestHibernateToManyProperty(Class<?> domainClass = CSPBTestEntityWithMany, String propertyName = "items") {
