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 05fcd164f06a5f9a05d24d7b6bcc01fadb8c0905 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Mon Mar 2 10:30:40 2026 -0600 Clean up GrailsPropertyBinder/ManyToOneBinder/OneToOneBinder to use concrete types; eliminate OneToOne cast and HibernateToOneProperty overload --- .../domainbinding/binder/GrailsPropertyBinder.java | 21 ++++----- .../cfg/domainbinding/binder/ManyToOneBinder.java | 19 ++++++-- .../cfg/domainbinding/binder/OneToOneBinder.java | 8 ++-- .../secondpass/CollectionSecondPassBinder.java | 5 +- .../cfg/domainbinding/OneToOneBinderSpec.groovy | 53 ++++++++++++---------- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsPropertyBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsPropertyBinder.java index 4d949b2746..e7332f0b24 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsPropertyBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsPropertyBinder.java @@ -21,9 +21,10 @@ package org.grails.orm.hibernate.cfg.domainbinding.binder; import jakarta.annotation.Nonnull; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEnumProperty; +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.hibernate.HibernatePersistentProperty; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToOneProperty; import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Table; @@ -78,17 +79,13 @@ public class GrailsPropertyBinder { if (currentGrailsProp instanceof HibernateEnumProperty) { value = enumTypeBinder.bindEnumType(currentGrailsProp, currentGrailsProp.getType(), table, path); - } else if (currentGrailsProp instanceof HibernateToOneProperty toOne) { - if (toOne.isValidHibernateOneToOne()) { - value = - oneToOneBinder.bindOneToOne( - (org.grails.datastore.mapping.model.types.OneToOne) toOne, - persistentClass, - table, - path); - } else { - value = manyToOneBinder.bindManyToOne(toOne, table, path); - } + } else if (currentGrailsProp instanceof HibernateOneToOneProperty oneToOne + && oneToOne.isValidHibernateOneToOne()) { + value = oneToOneBinder.bindOneToOne(oneToOne, persistentClass, table, path); + } else if (currentGrailsProp instanceof HibernateOneToOneProperty oneToOne) { + value = manyToOneBinder.bindManyToOne(oneToOne, table, path); + } else if (currentGrailsProp instanceof HibernateManyToOneProperty manyToOne) { + value = manyToOneBinder.bindManyToOne(manyToOne, table, path); } else if (currentGrailsProp instanceof HibernateToManyProperty toMany && !currentGrailsProp.isSerializableType()) { // HibernateToManyProperty diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ManyToOneBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ManyToOneBinder.java index 9dd8fe4f9f..bad0ebc63e 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ManyToOneBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/ManyToOneBinder.java @@ -29,6 +29,7 @@ import org.grails.orm.hibernate.cfg.PropertyConfig; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateAssociation; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToManyProperty; +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.hibernate.HibernateToOneProperty; import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher; @@ -77,14 +78,24 @@ public class ManyToOneBinder { new SimpleValueColumnFetcher()); } - /** Binds a to-one (many-to-one or one-to-one) association. */ + /** Binds a many-to-one association. */ public ManyToOne bindManyToOne( - HibernateToOneProperty property, org.hibernate.mapping.Table table, String path) { + HibernateManyToOneProperty property, org.hibernate.mapping.Table table, String path) { + GrailsHibernatePersistentEntity refDomainClass = property.getHibernateAssociatedEntity(); + return doBind(property, refDomainClass, isCompositeIdentifier(refDomainClass), table, path); + } + + /** + * Binds a one-to-one association where the foreign key resides on the other side (not a true + * Hibernate one-to-one), i.e. {@code isHibernateOneToOne()} is false. + */ + public ManyToOne bindManyToOne( + HibernateOneToOneProperty property, org.hibernate.mapping.Table table, String path) { GrailsHibernatePersistentEntity refDomainClass = property.getHibernateAssociatedEntity(); boolean isComposite = isCompositeIdentifier(refDomainClass); ManyToOne manyToOne = doBind(property, refDomainClass, isComposite, table, path); - if (property instanceof HibernateOneToOneProperty oneToOne && !isComposite) { - bindOneToOneUniqueKey(oneToOne, manyToOne); + if (!isComposite) { + bindOneToOneUniqueKey(property, manyToOne); } return manyToOne; } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/OneToOneBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/OneToOneBinder.java index 40f3f763a3..236e2a6e07 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/OneToOneBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/OneToOneBinder.java @@ -21,6 +21,7 @@ package org.grails.orm.hibernate.cfg.domainbinding.binder; import org.grails.datastore.mapping.model.types.Association; import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; import org.grails.orm.hibernate.cfg.PropertyConfig; +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOneProperty; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty; import org.hibernate.FetchMode; import org.hibernate.boot.spi.MetadataBuildingContext; @@ -50,12 +51,12 @@ public class OneToOneBinder { } public OneToOne bindOneToOne( - final org.grails.datastore.mapping.model.types.OneToOne property, + final HibernateOneToOneProperty property, PersistentClass owner, org.hibernate.mapping.Table table, String path) { OneToOne oneToOne = new OneToOne(metadataBuildingContext, table, owner); - PropertyConfig config = ((HibernatePersistentProperty) property).getMappedForm(); + PropertyConfig config = property.getMappedForm(); final Association otherSide = property.getInverseSide(); final boolean hasOne = otherSide != null && otherSide.isHasOne(); @@ -78,8 +79,7 @@ public class OneToOneBinder { oneToOne.setReferenceToPrimaryKey(false); if (hasOne || otherSide == null) { - simpleValueBinder.bindSimpleValue( - (HibernatePersistentProperty) property, null, oneToOne, path); + simpleValueBinder.bindSimpleValue(property, null, oneToOne, path); } else { oneToOne.setReferencedPropertyName(otherSide.getName()); } 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 cb3ce556f7..9b54553ca5 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 @@ -33,7 +33,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToManyP import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToManyProperty; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToOneProperty; +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToOneProperty; import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher; import org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder; import org.hibernate.MappingException; @@ -208,7 +208,8 @@ public class CollectionSecondPassBinder { private void bindBidirectionalMapElement( HibernateToManyProperty property, Collection collection) { - HibernateToOneProperty otherSide = (HibernateToOneProperty) property.getHibernateInverseSide(); + HibernateManyToOneProperty otherSide = + (HibernateManyToOneProperty) property.getHibernateInverseSide(); ManyToOne element = manyToOneBinder.bindManyToOne(otherSide, collection.getCollectionTable(), EMPTY_PATH); element.setReferencedEntityName(otherSide.getOwner().getName()); diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/OneToOneBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/OneToOneBinderSpec.groovy index de96426166..4b5e9d2073 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/OneToOneBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/OneToOneBinderSpec.groovy @@ -2,8 +2,10 @@ package org.grails.orm.hibernate.cfg.domainbinding import grails.gorm.specs.HibernateGormDatastoreSpec import org.grails.datastore.mapping.model.types.OneToOne as GormOneToOne +import org.grails.datastore.mapping.model.MappingContext import org.grails.datastore.mapping.model.PersistentEntity -import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateOneToOneProperty +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity import org.grails.orm.hibernate.cfg.PropertyConfig import org.hibernate.FetchMode import org.hibernate.mapping.OneToOne as HibernateOneToOne @@ -29,8 +31,8 @@ class OneToOneBinderSpec extends HibernateGormDatastoreSpec { given: def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() def ownerRoot = new RootClass(metadataBuildingContext) - - def gormOneToOne = Mock(GormOneToOne, additionalInterfaces: [HibernatePersistentProperty]) + + def gormOneToOne = Mock(TestOneToOne) def otherSide = Mock(GormOneToOne) def owner = Mock(PersistentEntity) def otherOwner = Mock(PersistentEntity) @@ -38,17 +40,16 @@ class OneToOneBinderSpec extends HibernateGormDatastoreSpec { gormOneToOne.getInverseSide() >> otherSide gormOneToOne.getName() >> "myOneToOne" gormOneToOne.getOwner() >> owner - + gormOneToOne.getMappedForm() >> new PropertyConfig() + otherSide.isHasOne() >> false otherSide.getOwner() >> otherOwner otherSide.getName() >> "otherSide" - - otherOwner.getName() >> "OtherEntity" - ((HibernatePersistentProperty)gormOneToOne).getMappedForm() >> new PropertyConfig() + otherOwner.getName() >> "OtherEntity" when: - def hibernateOneToOne = binder.bindOneToOne(gormOneToOne as GormOneToOne, ownerRoot, null, "") + def hibernateOneToOne = binder.bindOneToOne(gormOneToOne, ownerRoot, null, "") then: hibernateOneToOne instanceof HibernateOneToOne @@ -65,8 +66,8 @@ class OneToOneBinderSpec extends HibernateGormDatastoreSpec { given: def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() def ownerRoot = new RootClass(metadataBuildingContext) - - def gormOneToOne = Mock(GormOneToOne, additionalInterfaces: [HibernatePersistentProperty]) + + def gormOneToOne = Mock(TestOneToOne) def otherSide = Mock(GormOneToOne) def owner = Mock(PersistentEntity) def otherOwner = Mock(PersistentEntity) @@ -74,17 +75,15 @@ class OneToOneBinderSpec extends HibernateGormDatastoreSpec { gormOneToOne.getInverseSide() >> otherSide gormOneToOne.getName() >> "myOneToOne" gormOneToOne.getOwner() >> owner - + gormOneToOne.getMappedForm() >> new PropertyConfig() + otherSide.isHasOne() >> true otherSide.getOwner() >> otherOwner - - otherOwner.getName() >> "OtherEntity" - def propertyConfig = new PropertyConfig() - ((HibernatePersistentProperty)gormOneToOne).getMappedForm() >> propertyConfig + otherOwner.getName() >> "OtherEntity" when: - def hibernateOneToOne = binder.bindOneToOne(gormOneToOne as GormOneToOne, ownerRoot, null, "") + def hibernateOneToOne = binder.bindOneToOne(gormOneToOne, ownerRoot, null, "") then: hibernateOneToOne.isConstrained() @@ -96,26 +95,32 @@ class OneToOneBinderSpec extends HibernateGormDatastoreSpec { given: def metadataBuildingContext = getGrailsDomainBinder().getMetadataBuildingContext() def ownerRoot = new RootClass(metadataBuildingContext) - - def gormOneToOne = Mock(GormOneToOne, additionalInterfaces: [HibernatePersistentProperty]) + + def propertyConfig = new PropertyConfig() + propertyConfig.setFetch("join") + + def gormOneToOne = Mock(TestOneToOne) def otherSide = Mock(GormOneToOne) def owner = Mock(PersistentEntity) def otherOwner = Mock(PersistentEntity) - - def propertyConfig = new PropertyConfig() - propertyConfig.setFetch("join") gormOneToOne.getInverseSide() >> otherSide gormOneToOne.getOwner() >> owner + gormOneToOne.getMappedForm() >> propertyConfig + otherSide.getOwner() >> otherOwner otherSide.isHasOne() >> false - - ((HibernatePersistentProperty)gormOneToOne).getMappedForm() >> propertyConfig when: - def hibernateOneToOne = binder.bindOneToOne(gormOneToOne as GormOneToOne, ownerRoot, null, "") + def hibernateOneToOne = binder.bindOneToOne(gormOneToOne, ownerRoot, null, "") then: hibernateOneToOne.getFetchMode() == FetchMode.JOIN } } + +abstract class TestOneToOne extends HibernateOneToOneProperty { + TestOneToOne(PersistentEntity owner, MappingContext context, java.beans.PropertyDescriptor descriptor) { + super(owner, context, descriptor) + } +}
