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 8042c26f84888df4e3c0a29f992cfd4a38637722 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Thu Feb 5 21:06:17 2026 -0600 progress --- .../orm/hibernate/cfg/HibernateToManyProperty.java | 16 +++++++++ .../cfg/domainbinding/CollectionBinder.java | 26 +++++--------- .../ShouldCollectionBindWithJoinColumn.java | 17 --------- .../cfg/domainbinding/TableForManyCalculator.java | 6 +--- .../ShouldCollectionBindWithJoinColumnSpec.groovy | 40 ---------------------- .../TableForManyCalculatorSpec.groovy | 5 ++- 6 files changed, 28 insertions(+), 82 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateToManyProperty.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateToManyProperty.java index 57fe8d2e76..8ed62697bc 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateToManyProperty.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateToManyProperty.java @@ -2,6 +2,11 @@ package org.grails.orm.hibernate.cfg; import org.grails.datastore.mapping.model.PersistentEntity; import org.grails.datastore.mapping.model.types.Association; +import org.grails.datastore.mapping.model.types.Basic; +import org.grails.datastore.mapping.model.types.ManyToMany; +import org.grails.datastore.mapping.model.types.OneToMany; + +import java.util.Map; /** * Marker interface for Hibernate associations @@ -31,4 +36,15 @@ public interface HibernateToManyProperty extends GrailsHibernatePersistentProper default boolean isBidirectionalOneToManyMap() { return ((Association) this).isBidirectionalOneToManyMap(); } + + /** + * @return Whether the collection should be bound with a foreign key + */ + default boolean shouldBindWithForeignKey() { + return ((this instanceof OneToMany) && isBidirectional() || + !isUnidirectionalOneToMany()) && + !Map.class.isAssignableFrom(getType()) && + !(this instanceof ManyToMany) && + !(this instanceof Basic); + } } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinder.java index 989befa998..c969a7f25b 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CollectionBinder.java @@ -117,7 +117,7 @@ public class CollectionBinder { collection.setOrphanDelete(pc.getCascade().equals(CascadeBehavior.ALL_DELETE_ORPHAN.getValue())); } // if it's a one-to-many mapping - if (shouldBindCollectionWithForeignKey(property)) { + if (property.shouldBindWithForeignKey()) { OneToMany oneToMany = new OneToMany(metadataBuildingContext, collection.getOwner()); collection.setElement(oneToMany); bindOneToMany((org.grails.datastore.mapping.model.types.OneToMany) property, oneToMany, mappings); @@ -220,7 +220,7 @@ public class CollectionBinder { } oneToMany.setAssociatedClass(associatedClass); - if (shouldBindCollectionWithForeignKey(property)) { + if (property.shouldBindWithForeignKey()) { collection.setCollectionTable(associatedClass.getTable()); } @@ -251,7 +251,7 @@ public class CollectionBinder { GrailsHibernatePersistentProperty otherSide = (GrailsHibernatePersistentProperty) property.getInverseSide(); - if ((otherSide instanceof org.grails.datastore.mapping.model.types.ToOne) && shouldBindCollectionWithForeignKey(property)) { + if ((otherSide instanceof org.grails.datastore.mapping.model.types.ToOne) && property.shouldBindWithForeignKey()) { linkBidirectionalOneToMany(collection, associatedClass, key, otherSide); @@ -303,10 +303,10 @@ public class CollectionBinder { } else { // TODO support unidirectional many-to-many } - } else if (new ShouldCollectionBindWithJoinColumn().apply(property)) { + } else if (property.supportsJoinColumnMapping()) { bindCollectionWithJoinTable(property, mappings, collection, propConfig, sessionFactoryBeanName); - } else if (ofNullable(property).map(PersistentProperty::isUnidirectionalOneToMany).orElse(false)) { + } else if (property.isUnidirectionalOneToMany()) { // for non-inverse one-to-many, with a not-null fk, add a backref! // there are problems with list and map mappings and join columns relating to duplicate key constraints // TODO change this when HHH-1268 is resolved @@ -454,16 +454,9 @@ public class CollectionBinder { return null; } - /* - * We bind collections with foreign keys if specified in the mapping and only if - * it is a unidirectional one-to-many that is. - */ - private boolean shouldBindCollectionWithForeignKey(HibernateToManyProperty property) { - return ((property instanceof org.grails.datastore.mapping.model.types.OneToMany) && property.isBidirectional() || - !(boolean) new ShouldCollectionBindWithJoinColumn().apply(property)) && - !Map.class.isAssignableFrom(property.getType()) && - !(property instanceof ManyToMany) && - !(property instanceof Basic); + private PersistentClass getAssociatedClass(Map<?, ?> persistentClasses, HibernateToManyProperty property) { + String associatedClassName = property.getAssociatedEntity().getName(); + return (PersistentClass) persistentClasses.get(associatedClassName); } private String getNameForPropertyAndPath(PersistentProperty property, String path) { @@ -790,8 +783,7 @@ public class CollectionBinder { mapping = persistentEntity.getMappedForm(); } boolean hasCompositeIdentifier = mapping != null && mapping.hasCompositeIdentifier(); - if ((new ShouldCollectionBindWithJoinColumn().apply((HibernateToManyProperty) property) && hasCompositeIdentifier) || - (hasCompositeIdentifier && ( property instanceof ManyToMany))) { + if (hasCompositeIdentifier && property.supportsJoinColumnMapping()) { CompositeIdentity ci = (CompositeIdentity) mapping.getIdentity(); new CompositeIdentifierToManyToOneBinder(namingStrategy).bindCompositeIdentifierToManyToOne((GrailsHibernatePersistentProperty) property, key, ci, refDomainClass, EMPTY_PATH); } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumn.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumn.java deleted file mode 100644 index 312a8b44b4..0000000000 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumn.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.grails.orm.hibernate.cfg.domainbinding; - -import java.util.function.Function; - -import org.grails.datastore.mapping.model.PersistentProperty; -import org.grails.datastore.mapping.model.types.Basic; -import org.grails.orm.hibernate.cfg.HibernateToManyProperty; - -import static java.util.Optional.ofNullable; - -public class ShouldCollectionBindWithJoinColumn implements Function<HibernateToManyProperty,Boolean> { - - @Override - public Boolean apply(HibernateToManyProperty property) { - return (ofNullable(property).map(PersistentProperty::isUnidirectionalOneToMany).orElse(false) || (property instanceof Basic)); - } -} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculator.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculator.java index 44f253f314..48c75ba495 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculator.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculator.java @@ -19,26 +19,22 @@ public class TableForManyCalculator { private final PersistentEntityNamingStrategy namingStrategy; private final TableNameFetcher tableNameFetcher; private final BackticksRemover backticksRemover; - private final ShouldCollectionBindWithJoinColumn shouldCollectionBindWithJoinColumn; private final BackTigsTrimmer backTigsTrimmer; public TableForManyCalculator(PersistentEntityNamingStrategy namingStrategy) { this.namingStrategy = namingStrategy; tableNameFetcher = new TableNameFetcher(namingStrategy); backticksRemover = new BackticksRemover(); - shouldCollectionBindWithJoinColumn = new ShouldCollectionBindWithJoinColumn(); backTigsTrimmer = new BackTigsTrimmer(); } protected TableForManyCalculator(PersistentEntityNamingStrategy namingStrategy , TableNameFetcher tableNameFetcher , BackticksRemover backticksRemover - , ShouldCollectionBindWithJoinColumn shouldCollectionBindWithJoinColumn , BackTigsTrimmer backTigsTrimmer) { this.namingStrategy = namingStrategy; this.tableNameFetcher = tableNameFetcher; this.backticksRemover = backticksRemover; - this.shouldCollectionBindWithJoinColumn = shouldCollectionBindWithJoinColumn; this.backTigsTrimmer = backTigsTrimmer; } @@ -90,7 +86,7 @@ public class TableForManyCalculator { return backticksRemover.apply(right) + UNDERSCORE + backticksRemover.apply(s2); } - if (shouldCollectionBindWithJoinColumn.apply(property)) { + if (property.supportsJoinColumnMapping()) { if (hasJoinTableMapping) { return jt.getName(); } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumnSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumnSpec.groovy deleted file mode 100644 index 7450c1dd33..0000000000 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/ShouldCollectionBindWithJoinColumnSpec.groovy +++ /dev/null @@ -1,40 +0,0 @@ -package org.grails.orm.hibernate.cfg.domainbinding - -import org.grails.orm.hibernate.cfg.HibernateToManyProperty -import spock.lang.Specification - -class ShouldCollectionBindWithJoinColumnSpec extends Specification { - - def "returns true when property is unidirectional one-to-many"() { - given: - def calc = new ShouldCollectionBindWithJoinColumn() - HibernateToManyProperty prop = Mock(HibernateToManyProperty) { - isUnidirectionalOneToMany() >> true // Test the unidirectional path - } - - expect: - calc.apply(prop) - } - - def "returns false when property is not unidirectional one-to-many and not Basic"() { - given: - def calc = new ShouldCollectionBindWithJoinColumn() - // Mocking HibernateToManyProperty, and isUnidirectionalOneToMany is false. - // The 'property instanceof Basic' check will be false for a mock of HibernateToManyProperty. - // Therefore, the result should be false. - HibernateToManyProperty prop = Mock(HibernateToManyProperty) { - isUnidirectionalOneToMany() >> false // Test the non-unidirectional path - } - - expect: - !calc.apply(prop) - } - - def "returns false when property is null"() { - given: - def calc = new ShouldCollectionBindWithJoinColumn() - - expect: - !calc.apply(null) - } -} diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculatorSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculatorSpec.groovy index 5e136c0215..143c1a7e28 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculatorSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/TableForManyCalculatorSpec.groovy @@ -21,10 +21,9 @@ class TableForManyCalculatorSpec extends Specification { def namingStrategy = Stub(PersistentEntityNamingStrategy) def tableNameFetcher = Stub(TableNameFetcher) def backticksRemover = Stub(BackticksRemover) - def shouldBind = Stub(ShouldCollectionBindWithJoinColumn) def trimmer = Stub(BackTigsTrimmer) - def calculator = new TableForManyCalculator(namingStrategy, tableNameFetcher, backticksRemover, shouldBind, trimmer) + def calculator = new TableForManyCalculator(namingStrategy, tableNameFetcher, backticksRemover, trimmer) GrailsHibernatePersistentEntity ownerEntity = Stub(GrailsHibernatePersistentEntity) GrailsHibernatePersistentEntity associatedEntity = Stub(GrailsHibernatePersistentEntity) @@ -40,6 +39,7 @@ class TableForManyCalculatorSpec extends Specification { property.getAssociatedEntity() >> associatedEntity property.isOwningSide() >> isOwningSide property.getMappedForm() >> config + property.supportsJoinColumnMapping() >> shouldBindWithJoinColumn if (property instanceof ManyToMany) { ((ManyToMany)property).getInversePropertyName() >> "inverseProp" @@ -50,7 +50,6 @@ class TableForManyCalculatorSpec extends Specification { namingStrategy.resolveColumnName("inverseProp") >> "inverse_prop_col" tableNameFetcher.getTableName(ownerEntity) >> "owner_table" tableNameFetcher.getTableName(associatedEntity) >> "associated_table" - shouldBind.apply(_) >> shouldBindWithJoinColumn backticksRemover.apply(_) >> { String s -> s } trimmer.trimBackTigs(_) >> { String s -> s }
