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']
+    }
+}

Reply via email to