You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/03/03 23:27:31 UTC
(grails-core) 24/24: refactor: extract resolveJoinTableForeignKeyColumnName into HibernateToManyProperty
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 <wb...@mac.com>
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']
+ }
+}