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 b965e8aefd56f45fcb679ab0586b4fcbf80905b7 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Tue Mar 3 15:48:08 2026 -0600 efactor: extract BasicCollectionElementBinder from CollectionWithJoinTableBinder --- .../cfg/domainbinding/binder/CollectionBinder.java | 11 ++- .../hibernate/HibernateToManyProperty.java | 4 + .../secondpass/BasicCollectionElementBinder.java | 99 ++++++++++++++++++++++ .../secondpass/CollectionWithJoinTableBinder.java | 78 +++-------------- .../BasicCollectionElementBinderSpec.groovy | 82 ++++++++++++++++++ .../CollectionSecondPassBinderSpec.groovy | 2 +- .../CollectionWithJoinTableBinderSpec.groovy | 23 ++--- .../UnidirectionalOneToManyBinderSpec.groovy | 10 ++- 8 files changed, 224 insertions(+), 85 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 b397d360ad..71e1bf5fb3 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 @@ -28,6 +28,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.collectionType.CollectionType; 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.secondpass.BasicCollectionElementBinder; import org.grails.orm.hibernate.cfg.domainbinding.secondpass.BidirectionalOneToManyLinker; import org.grails.orm.hibernate.cfg.domainbinding.secondpass.CollectionKeyColumnUpdater; import org.grails.orm.hibernate.cfg.domainbinding.secondpass.BidirectionalMapElementBinder; @@ -102,12 +103,16 @@ public class CollectionBinder { metadataBuildingContext, namingStrategy, unidirectionalOneToManyInverseValuesBinder, - enumTypeBinder, compositeIdentifierToManyToOneBinder, - simpleValueColumnFetcher, collectionForPropertyConfigBinder, simpleValueColumnBinder, - new ColumnConfigToColumnBinder()); + new BasicCollectionElementBinder( + metadataBuildingContext, + namingStrategy, + enumTypeBinder, + simpleValueColumnBinder, + simpleValueColumnFetcher, + new ColumnConfigToColumnBinder())); this.collectionSecondPassBinder = new CollectionSecondPassBinder( new CollectionKeyColumnUpdater( diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyProperty.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyProperty.java index ea6d8d38ac..5dad0c18d9 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyProperty.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyProperty.java @@ -68,6 +68,10 @@ public interface HibernateToManyProperty .orElse(null); } + default boolean isBasic() { + return this instanceof Basic; + } + /** * @return Whether the collection should be bound with a foreign key */ diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinder.java new file mode 100644 index 0000000000..98918589d3 --- /dev/null +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinder.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.grails.orm.hibernate.cfg.domainbinding.secondpass; + +import static org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBinder.UNDERSCORE; + +import java.util.Optional; +import org.grails.datastore.mapping.model.types.Basic; +import org.grails.orm.hibernate.cfg.ColumnConfig; +import org.grails.orm.hibernate.cfg.PersistentEntityNamingStrategy; +import org.grails.orm.hibernate.cfg.PropertyConfig; +import org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnConfigToColumnBinder; +import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder; +import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder; +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; +import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover; +import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher; +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.mapping.BasicValue; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.Column; + +/** Binds the element value for a basic (scalar or enum) collection. */ +public class BasicCollectionElementBinder { + + private final MetadataBuildingContext metadataBuildingContext; + private final PersistentEntityNamingStrategy namingStrategy; + private final EnumTypeBinder enumTypeBinder; + private final SimpleValueColumnBinder simpleValueColumnBinder; + private final SimpleValueColumnFetcher simpleValueColumnFetcher; + private final ColumnConfigToColumnBinder columnConfigToColumnBinder; + + /** Creates a new {@link BasicCollectionElementBinder} instance. */ + public BasicCollectionElementBinder( + MetadataBuildingContext metadataBuildingContext, + PersistentEntityNamingStrategy namingStrategy, + EnumTypeBinder enumTypeBinder, + SimpleValueColumnBinder simpleValueColumnBinder, + SimpleValueColumnFetcher simpleValueColumnFetcher, + ColumnConfigToColumnBinder columnConfigToColumnBinder) { + this.metadataBuildingContext = metadataBuildingContext; + this.namingStrategy = namingStrategy; + this.enumTypeBinder = enumTypeBinder; + this.simpleValueColumnBinder = simpleValueColumnBinder; + this.simpleValueColumnFetcher = simpleValueColumnFetcher; + this.columnConfigToColumnBinder = columnConfigToColumnBinder; + } + + /** Creates and binds a {@link BasicValue} element for the given basic collection property. */ + public BasicValue bind(HibernateToManyProperty property, Collection collection) { + BasicValue element = new BasicValue(metadataBuildingContext, collection.getCollectionTable()); + final Class<?> referencedType = ((Basic) property).getComponentType(); + final boolean isEnum = referencedType.isEnum(); + var joinColumnMappingOptional = + Optional.ofNullable(property.getMappedForm()).map(PropertyConfig::getJoinTableColumnConfig); + String columnName; + if (joinColumnMappingOptional.isPresent()) { + columnName = joinColumnMappingOptional.get().getName(); + } else { + var clazz = namingStrategy.resolveColumnName(referencedType.getName()); + var prop = namingStrategy.resolveTableName(property.getName()); + columnName = + isEnum + ? clazz + : new BackticksRemover().apply(prop) + + UNDERSCORE + + new BackticksRemover().apply(clazz); + } + if (isEnum) { + enumTypeBinder.bindEnumType(property, referencedType, element, columnName); + } else { + String typeName = property.getTypeName(referencedType); + simpleValueColumnBinder.bindSimpleValue(element, typeName, columnName, true); + if (joinColumnMappingOptional.isPresent()) { + Column column = simpleValueColumnFetcher.getColumnForSimpleValue(element); + ColumnConfig columnConfig = joinColumnMappingOptional.get(); + final PropertyConfig mappedForm = property.getMappedForm(); + columnConfigToColumnBinder.bindColumnConfigToColumn(column, columnConfig, mappedForm); + } + } + return element; + } +} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinder.java index 29b694b44c..e880b21c56 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinder.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinder.java @@ -22,16 +22,11 @@ import static org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBind import jakarta.annotation.Nonnull; import java.util.Optional; -import org.grails.datastore.mapping.model.types.Basic; import org.grails.orm.hibernate.cfg.*; import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionForPropertyConfigBinder; -import org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnConfigToColumnBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder; -import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder; import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty; -import org.grails.orm.hibernate.cfg.domainbinding.util.BackticksRemover; -import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher; import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.mapping.*; @@ -45,33 +40,27 @@ public class CollectionWithJoinTableBinder { private final PersistentEntityNamingStrategy namingStrategy; private final UnidirectionalOneToManyInverseValuesBinder unidirectionalOneToManyInverseValuesBinder; - private final EnumTypeBinder enumTypeBinder; private final CompositeIdentifierToManyToOneBinder compositeIdentifierToManyToOneBinder; - private final SimpleValueColumnFetcher simpleValueColumnFetcher; private final CollectionForPropertyConfigBinder collectionForPropertyConfigBinder; private final SimpleValueColumnBinder simpleValueColumnBinder; - private final ColumnConfigToColumnBinder columnConfigToColumnBinder; + private final BasicCollectionElementBinder basicCollectionElementBinder; /** Creates a new {@link CollectionWithJoinTableBinder} instance. */ public CollectionWithJoinTableBinder( MetadataBuildingContext metadataBuildingContext, PersistentEntityNamingStrategy namingStrategy, UnidirectionalOneToManyInverseValuesBinder unidirectionalOneToManyInverseValuesBinder, - EnumTypeBinder enumTypeBinder, CompositeIdentifierToManyToOneBinder compositeIdentifierToManyToOneBinder, - SimpleValueColumnFetcher simpleValueColumnFetcher, CollectionForPropertyConfigBinder collectionForPropertyConfigBinder, SimpleValueColumnBinder simpleValueColumnBinder, - ColumnConfigToColumnBinder columnConfigToColumnBinder) { + BasicCollectionElementBinder basicCollectionElementBinder) { this.metadataBuildingContext = metadataBuildingContext; this.namingStrategy = namingStrategy; this.unidirectionalOneToManyInverseValuesBinder = unidirectionalOneToManyInverseValuesBinder; - this.enumTypeBinder = enumTypeBinder; this.compositeIdentifierToManyToOneBinder = compositeIdentifierToManyToOneBinder; - this.simpleValueColumnFetcher = simpleValueColumnFetcher; this.collectionForPropertyConfigBinder = collectionForPropertyConfigBinder; this.simpleValueColumnBinder = simpleValueColumnBinder; - this.columnConfigToColumnBinder = columnConfigToColumnBinder; + this.basicCollectionElementBinder = basicCollectionElementBinder; } /** Bind collection with join table. */ @@ -82,73 +71,34 @@ public class CollectionWithJoinTableBinder { collection.setInverse(false); SimpleValue element; - final boolean isBasicCollectionType = property instanceof Basic; - if (isBasicCollectionType) { - element = new BasicValue(metadataBuildingContext, collection.getCollectionTable()); + if (property.isBasic()) { + element = basicCollectionElementBinder.bind(property, collection); } else { - // for a normal unidirectional one-to-many we use a join column element = new ManyToOne(metadataBuildingContext, collection.getCollectionTable()); unidirectionalOneToManyInverseValuesBinder.bindUnidirectionalOneToManyInverseValues( property, (ManyToOne) element); - } - - String columnName; - - var joinColumnMappingOptional = - Optional.ofNullable(property.getMappedForm()).map(PropertyConfig::getJoinTableColumnConfig); - if (isBasicCollectionType) { - final Class<?> referencedType = ((Basic) property).getComponentType(); - final boolean isEnum = referencedType.isEnum(); - if (joinColumnMappingOptional.isPresent()) { - columnName = joinColumnMappingOptional.get().getName(); - } else { - var clazz = namingStrategy.resolveColumnName(referencedType.getName()); - var prop = namingStrategy.resolveTableName(property.getName()); - columnName = - isEnum - ? clazz - : new BackticksRemover().apply(prop) - + UNDERSCORE - + new BackticksRemover().apply(clazz); - } - - if (isEnum) { - enumTypeBinder.bindEnumType(property, referencedType, (BasicValue) element, columnName); - } else { - - String typeName = property.getTypeName(referencedType); - - simpleValueColumnBinder.bindSimpleValue(element, typeName, columnName, true); - if (joinColumnMappingOptional.isPresent()) { - Column column = simpleValueColumnFetcher.getColumnForSimpleValue(element); - ColumnConfig columnConfig = joinColumnMappingOptional.get(); - final PropertyConfig mappedForm = property.getMappedForm(); - columnConfigToColumnBinder.bindColumnConfigToColumn(column, columnConfig, mappedForm); - } - } - } else { final var domainClass = property.getHibernateAssociatedEntity(); - if (domainClass != null) { + var joinColumnMappingOptional = + Optional.ofNullable(property.getMappedForm()) + .map(PropertyConfig::getJoinTableColumnConfig); if (domainClass.getHibernateCompositeIdentity().isPresent()) { CompositeIdentity ci = domainClass.getHibernateCompositeIdentity().get(); compositeIdentifierToManyToOneBinder.bindCompositeIdentifierToManyToOne( property, element, ci, domainClass, EMPTY_PATH); } else { - if (joinColumnMappingOptional.isPresent()) { - columnName = joinColumnMappingOptional.get().getName(); - } else { - var decapitalize = domainClass.getHibernateRootEntity().getJavaClass().getSimpleName(); - columnName = namingStrategy.resolveColumnName(decapitalize) + FOREIGN_KEY_SUFFIX; - } - + String columnName = + joinColumnMappingOptional.isPresent() + ? joinColumnMappingOptional.get().getName() + : namingStrategy.resolveColumnName( + domainClass.getHibernateRootEntity().getJavaClass().getSimpleName()) + + FOREIGN_KEY_SUFFIX; simpleValueColumnBinder.bindSimpleValue(element, "long", columnName, true); } } } collection.setElement(element); - collectionForPropertyConfigBinder.bindCollectionForPropertyConfig(collection, property); } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinderSpec.groovy new file mode 100644 index 0000000000..d623ed7c61 --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/BasicCollectionElementBinderSpec.groovy @@ -0,0 +1,82 @@ +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.ColumnConfigToColumnBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder +import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty +import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher +import org.hibernate.mapping.BasicValue +import org.hibernate.mapping.Collection +import org.hibernate.mapping.RootClass +import org.hibernate.mapping.Set +import org.hibernate.mapping.Table +import org.hibernate.type.spi.TypeConfiguration +import spock.lang.Subject + +class BasicCollectionElementBinderSpec extends HibernateGormDatastoreSpec { + + @Subject + BasicCollectionElementBinder binder + + EnumTypeBinder enumTypeBinder = Mock(EnumTypeBinder) + + void setup() { + def domainBinder = getGrailsDomainBinder() + binder = new BasicCollectionElementBinder( + domainBinder.metadataBuildingContext, + domainBinder.namingStrategy, + enumTypeBinder, + new SimpleValueColumnBinder(), + new SimpleValueColumnFetcher(), + new ColumnConfigToColumnBinder() + ) + } + + private Collection collectionWithTable(String tableName) { + def mbc = getGrailsDomainBinder().metadataBuildingContext + def collection = new Set(mbc, new RootClass(mbc)) + collection.setCollectionTable(new Table(tableName)) + return collection + } + + void "bind creates BasicValue with column for scalar collection"() { + given: + def entity = createPersistentEntity(BCEBAuthor) + HibernateToManyProperty property = (HibernateToManyProperty) entity.getPropertyByName("tags") + Collection collection = collectionWithTable("bceb_author_tags") + + when: + BasicValue element = binder.bind(property, collection) + + then: + element != null + element.getColumnSpan() > 0 + 0 * enumTypeBinder.bindEnumType(*_) + } + + void "bind delegates to enumTypeBinder for enum collection"() { + given: + def entity = createPersistentEntity(BCEBAuthor) + HibernateToManyProperty property = (HibernateToManyProperty) entity.getPropertyByName("statuses") + Collection collection = collectionWithTable("bceb_author_statuses") + + when: + BasicValue element = binder.bind(property, collection) + + then: + element != null + 1 * enumTypeBinder.bindEnumType(property, BCEBStatus, _ as BasicValue, _) + } +} + +enum BCEBStatus { ACTIVE, INACTIVE } + +@Entity +class BCEBAuthor { + Long id + java.util.Set<String> tags + java.util.Set<BCEBStatus> statuses + static hasMany = [tags: String, statuses: BCEBStatus] +} 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 d89e94b226..2cd4ee88dc 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 @@ -34,7 +34,7 @@ class CollectionSecondPassBinderSpec extends HibernateGormDatastoreSpec { def pkvc = new PrimaryKeyValueCreator(mbc) def botml = new BidirectionalOneToManyLinker(new org.grails.orm.hibernate.cfg.domainbinding.util.GrailsPropertyResolver()) def dkvb = new DependentKeyValueBinder(svb, citmto) - def cwjtb = new CollectionWithJoinTableBinder(mbc, ns, new UnidirectionalOneToManyInverseValuesBinder(), null, citmto, svcf, new CollectionForPropertyConfigBinder(), new SimpleValueColumnBinder(), null) + def cwjtb = new CollectionWithJoinTableBinder(mbc, ns, new UnidirectionalOneToManyInverseValuesBinder(), citmto, new CollectionForPropertyConfigBinder(), new SimpleValueColumnBinder(), new BasicCollectionElementBinder(mbc, ns, null, new SimpleValueColumnBinder(), svcf, null)) def uotmb = new UnidirectionalOneToManyBinder(cwjtb, mbc.getMetadataCollector()) def cfpcb = new CollectionForPropertyConfigBinder() def dcnf = new DefaultColumnNameFetcher(ns, new BackticksRemover()) diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinderSpec.groovy index c6b32a6fd2..abc62e0ebd 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionWithJoinTableBinderSpec.groovy @@ -4,11 +4,8 @@ import grails.gorm.annotation.Entity import grails.gorm.specs.HibernateGormDatastoreSpec import org.grails.datastore.mapping.model.PersistentEntity import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionForPropertyConfigBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnConfigToColumnBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder -import org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder import org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder -import org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty import org.hibernate.boot.spi.InFlightMetadataCollector import org.hibernate.mapping.Collection @@ -16,7 +13,6 @@ import org.hibernate.mapping.ManyToOne import org.hibernate.mapping.RootClass import org.hibernate.mapping.Set import org.hibernate.mapping.Table -import org.hibernate.type.spi.TypeConfiguration import spock.lang.Subject class CollectionWithJoinTableBinderSpec extends HibernateGormDatastoreSpec { @@ -25,12 +21,10 @@ class CollectionWithJoinTableBinderSpec extends HibernateGormDatastoreSpec { CollectionWithJoinTableBinder binder UnidirectionalOneToManyInverseValuesBinder unidirectionalOneToManyInverseValuesBinder = Mock(UnidirectionalOneToManyInverseValuesBinder) - EnumTypeBinder enumTypeBinder = Mock(EnumTypeBinder) CompositeIdentifierToManyToOneBinder compositeIdentifierToManyToOneBinder = Mock(CompositeIdentifierToManyToOneBinder) - SimpleValueColumnFetcher simpleValueColumnFetcher = Mock(SimpleValueColumnFetcher) CollectionForPropertyConfigBinder collectionForPropertyConfigBinder = Mock(CollectionForPropertyConfigBinder) + BasicCollectionElementBinder basicCollectionElementBinder = Mock(BasicCollectionElementBinder) SimpleValueColumnBinder simpleValueColumnBinder = new SimpleValueColumnBinder() - ColumnConfigToColumnBinder columnConfigToColumnBinder = new ColumnConfigToColumnBinder() void setup() { def domainBinder = getGrailsDomainBinder() @@ -38,37 +32,38 @@ class CollectionWithJoinTableBinderSpec extends HibernateGormDatastoreSpec { domainBinder.metadataBuildingContext, domainBinder.namingStrategy, unidirectionalOneToManyInverseValuesBinder, - enumTypeBinder, compositeIdentifierToManyToOneBinder, - simpleValueColumnFetcher, collectionForPropertyConfigBinder, simpleValueColumnBinder, - columnConfigToColumnBinder + basicCollectionElementBinder ) } - void "test bindCollectionWithJoinTable for basic type"() { + void "test bindCollectionWithJoinTable delegates to BasicCollectionElementBinder for basic type"() { given: PersistentEntity authorEntity = createPersistentEntity(CWJTBAuthor) HibernateToManyProperty property = (HibernateToManyProperty) authorEntity.getPropertyByName("tags") def domainBinder = getGrailsDomainBinder() InFlightMetadataCollector mappings = Mock(InFlightMetadataCollector) - mappings.getTypeConfiguration() >> new TypeConfiguration() def owner = new RootClass(domainBinder.metadataBuildingContext) Collection collection = new Set(domainBinder.metadataBuildingContext, owner) collection.setCollectionTable(new Table("CWJTB_TAGS")) + def basicValue = new org.hibernate.mapping.BasicValue(domainBinder.metadataBuildingContext, collection.getCollectionTable()) + basicCollectionElementBinder.bind(property, collection) >> basicValue + when: binder.bindCollectionWithJoinTable(property, mappings, collection) then: - collection.getElement() != null + 1 * basicCollectionElementBinder.bind(property, collection) >> basicValue + collection.getElement() == basicValue 1 * collectionForPropertyConfigBinder.bindCollectionForPropertyConfig(collection, property) } - void "test bindCollectionWithJoinTable for entity association"() { + void "test bindCollectionWithJoinTable creates ManyToOne element for entity association"() { given: createPersistentEntity(CWJTBBook) PersistentEntity authorEntity = createPersistentEntity(CWJTBAuthor) diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/UnidirectionalOneToManyBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/UnidirectionalOneToManyBinderSpec.groovy index 56682ccb04..c26c011306 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/UnidirectionalOneToManyBinderSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/UnidirectionalOneToManyBinderSpec.groovy @@ -49,12 +49,16 @@ class UnidirectionalOneToManyBinderSpec extends HibernateGormDatastoreSpec { metadataBuildingContext, namingStrategy, unidirectionalOneToManyInverseValuesBinder, - enumTypeBinder, compositeIdentifierToManyToOneBinder, - simpleValueColumnFetcher, collectionForPropertyConfigBinder, new SimpleValueColumnBinder(), - new ColumnConfigToColumnBinder() + new BasicCollectionElementBinder( + metadataBuildingContext, + namingStrategy, + enumTypeBinder, + new SimpleValueColumnBinder(), + simpleValueColumnFetcher, + new ColumnConfigToColumnBinder()) ) binder = new UnidirectionalOneToManyBinder(collectionWithJoinTableBinder, grailsDomainBinder.metadataBuildingContext.metadataCollector) }
