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 2900b582eeae1d33a5d7c132033c75b29dd81ede Author: Walter Duque de Estrada <[email protected]> AuthorDate: Tue Mar 3 16:46:20 2026 -0600 refactor: extract resolveJoinTableForeignKeyColumnName into HibernateToManyProperty --- .../hibernate/HibernateToManyProperty.java | 11 +++ .../secondpass/CollectionWithJoinTableBinder.java | 15 +--- .../hibernate/HibernateToManyPropertySpec.groovy | 81 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 12 deletions(-) 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 5dad0c18d9..542b426b3c 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 @@ -112,4 +112,15 @@ public interface HibernateToManyProperty + GrailsDomainBinder.UNDERSCORE + IndexedCollection.DEFAULT_ELEMENT_COLUMN_NAME); } + + default String resolveJoinTableForeignKeyColumnName(PersistentEntityNamingStrategy namingStrategy) { + return java.util.Optional.ofNullable(getMappedForm()) + .map(PropertyConfig::getJoinTableColumnConfig) + .map(ColumnConfig::getName) + .orElseGet( + () -> + namingStrategy.resolveColumnName( + getHibernateAssociatedEntity().getHibernateRootEntity().getJavaClass().getSimpleName()) + + GrailsDomainBinder.FOREIGN_KEY_SUFFIX); + } } 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 e83dea0456..be671fdf8f 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 @@ -21,7 +21,6 @@ package org.grails.orm.hibernate.cfg.domainbinding.secondpass; import static org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBinder.*; import jakarta.annotation.Nonnull; -import java.util.Optional; import org.grails.orm.hibernate.cfg.*; import org.grails.orm.hibernate.cfg.domainbinding.binder.CollectionForPropertyConfigBinder; import org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdentifierToManyToOneBinder; @@ -72,21 +71,13 @@ public class CollectionWithJoinTableBinder { element = unidirectionalOneToManyInverseValuesBinder.bind(property, collection); final var domainClass = property.getHibernateAssociatedEntity(); if (domainClass != null) { - var joinColumnMappingOptional = - Optional.ofNullable(property.getMappedForm()) - .map(PropertyConfig::getJoinTableColumnConfig); - if (domainClass.getHibernateCompositeIdentity().isPresent()) { + if (domainClass.getHibernateCompositeIdentity().isPresent()) { CompositeIdentity ci = domainClass.getHibernateCompositeIdentity().get(); compositeIdentifierToManyToOneBinder.bindCompositeIdentifierToManyToOne( property, element, ci, domainClass, EMPTY_PATH); } else { - String columnName = - joinColumnMappingOptional.isPresent() - ? joinColumnMappingOptional.get().getName() - : namingStrategy.resolveColumnName( - domainClass.getHibernateRootEntity().getJavaClass().getSimpleName()) - + FOREIGN_KEY_SUFFIX; - simpleValueColumnBinder.bindSimpleValue(element, "long", columnName, true); + simpleValueColumnBinder.bindSimpleValue( + element, "long", property.resolveJoinTableForeignKeyColumnName(namingStrategy), true); } } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyPropertySpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyPropertySpec.groovy new file mode 100644 index 0000000000..d597720af5 --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateToManyPropertySpec.groovy @@ -0,0 +1,81 @@ +/* + * 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.hibernate + +import grails.gorm.annotation.Entity +import grails.gorm.specs.HibernateGormDatastoreSpec +import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateToManyProperty + +class HibernateToManyPropertySpec extends HibernateGormDatastoreSpec { + + def setupSpec() { + manager.addAllDomainClasses([HTMPBook, HTMPAuthor, HTMPAuthorCustom]) + } + + void "resolveJoinTableForeignKeyColumnName derives name from associated entity when no explicit config"() { + given: + def authorEntity = mappingContext.getPersistentEntity(HTMPAuthor.name) + HibernateToManyProperty property = (HibernateToManyProperty) authorEntity.getPropertyByName("books") + def namingStrategy = getGrailsDomainBinder().namingStrategy + + when: + String columnName = property.resolveJoinTableForeignKeyColumnName(namingStrategy) + + then: + columnName == "htmpbook_id" + } + + void "resolveJoinTableForeignKeyColumnName uses explicit join table column name when configured"() { + given: + def authorEntity = mappingContext.getPersistentEntity(HTMPAuthorCustom.name) + HibernateToManyProperty property = (HibernateToManyProperty) authorEntity.getPropertyByName("books") + def namingStrategy = getGrailsDomainBinder().namingStrategy + + when: + String columnName = property.resolveJoinTableForeignKeyColumnName(namingStrategy) + + then: + columnName == "custom_book_fk" + } +} + +@Entity +class HTMPBook { + Long id + String title +} + +@Entity +class HTMPAuthor { + Long id + String name + Set<HTMPBook> books + static hasMany = [books: HTMPBook] +} + +@Entity +class HTMPAuthorCustom { + Long id + String name + Set<HTMPBook> books + static hasMany = [books: HTMPBook] + static mapping = { + books joinTable: [column: 'custom_book_fk'] + } +}
