This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch merge-hibernate6
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit d654ad1655272c33d61de17ba4fb774e55a025fa
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Jul 12 21:50:53 2025 -0500

    refactor IndexBinder
---
 .../orm/hibernate/cfg/GrailsDomainBinder.java      | 101 +++++----------------
 .../hibernate/cfg/domainbinding/IndexBinder.java   |  26 ++++++
 .../cfg/domainbinding/IndexBinderSpec.groovy       |  90 ++++++++++++++++++
 3 files changed, 138 insertions(+), 79 deletions(-)

diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
index 5cf0186fbe..db87d77c68 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
@@ -37,6 +37,7 @@ import 
org.grails.orm.hibernate.access.TraitPropertyAccessStrategy;
 import org.grails.orm.hibernate.cfg.domainbinding.ClassBinder;
 import org.grails.orm.hibernate.cfg.domainbinding.ColumnConfigToColumnBinder;
 import 
org.grails.orm.hibernate.cfg.domainbinding.ConfigureDerivedPropertiesConsumer;
+import org.grails.orm.hibernate.cfg.domainbinding.IndexBinder;
 import org.grails.orm.hibernate.cfg.domainbinding.NamingStrategyProvider;
 import org.grails.orm.hibernate.cfg.domainbinding.SimpleValueBinder;
 import org.grails.orm.hibernate.cfg.domainbinding.TypeNameProvider;
@@ -284,11 +285,10 @@ public class GrailsDomainBinder implements 
MetadataContributor {
         String type = getIndexColumnType(property, STRING_TYPE);
         String columnName1 = getIndexColumnName(property, 
sessionFactoryBeanName);
         new SimpleValueBinder().bindSimpleValue(value, type, columnName1, 
true);
-        PropertyConfig pc = getPropertyConfig(property);
-        if (pc != null && pc.getIndexColumn() != null) {
+        PropertyConfig mappedForm = getPropertyConfig(property);
+        if (mappedForm != null && mappedForm.getIndexColumn() != null) {
             Column column = getColumnForSimpleValue(value);
-            ColumnConfig columnConfig = 
getSingleColumnConfig(pc.getIndexColumn());
-            final PropertyConfig mappedForm = getPropertyConfig(property);
+            ColumnConfig columnConfig = 
getSingleColumnConfig(mappedForm.getIndexColumn());
             new ColumnConfigToColumnBinder().bindColumnConfigToColumn(column, 
columnConfig, mappedForm);
         }
 
@@ -1269,6 +1269,7 @@ public class GrailsDomainBinder implements 
MetadataContributor {
 
 
 
+
     /**
      * Binds a Grails domain class to the Hibernate runtime meta model
      *
@@ -2111,7 +2112,7 @@ public class GrailsDomainBinder implements 
MetadataContributor {
         PropertyConfig propertyConfig = getPropertyConfig(property);
         if (propertyConfig != null && !propertyConfig.getColumns().isEmpty()) {
             ColumnConfig columnConfig = propertyConfig.getColumns().get(0);
-            bindIndex(columnName, column, columnConfig, t);
+            new IndexBinder().bindIndex(columnName, column, columnConfig, t);
             final PropertyConfig mappedForm = getPropertyConfig(property);
             new ColumnConfigToColumnBinder().bindColumnConfigToColumn(column, 
columnConfig, mappedForm);
         }
@@ -2813,7 +2814,7 @@ public class GrailsDomainBinder implements 
MetadataContributor {
                                    String path, PropertyConfig propertyConfig, 
String sessionFactoryBeanName) {
         setTypeForPropertyConfig(grailsProp, simpleValue, propertyConfig);
         final PropertyConfig mappedForm = (PropertyConfig) 
grailsProp.getMapping().getMappedForm();
-        if (mappedForm.isDerived() && !(grailsProp instanceof TenantId)) {
+        if (mappedForm != null && mappedForm.isDerived() && !(grailsProp 
instanceof TenantId)) {
             Formula formula = new Formula();
             formula.setFormula(propertyConfig.getFormula());
             simpleValue.addFormula(formula);
@@ -2840,52 +2841,20 @@ public class GrailsDomainBinder implements 
MetadataContributor {
             // not all custom mapped properties will have column definitions,
             // in which case we still need to create a Hibernate column for
             // this value.
-            List<?> columnDefinitions = hasConfig ? propertyConfig.getColumns()
-                    : Arrays.asList(new Object[] { null });
-            if (columnDefinitions.isEmpty()) {
-                columnDefinitions = Arrays.asList(new Object[] { null });
-            }
-
-            for (Object columnDefinition : columnDefinitions) {
-                ColumnConfig cc = (ColumnConfig) columnDefinition;
-                Column column = new Column();
-
-                // Check for explicitly mapped column name and SQL type.
-                if (cc != null) {
-                    if (cc.getName() != null) {
-                        column.setName(cc.getName());
-                    }
-                    if (cc.getSqlType() != null) {
-                        column.setSqlType(cc.getSqlType());
-                    }
-                }
-
-                column.setValue(simpleValue);
-
-
-                if (cc != null) {
-                    if (cc.getLength() != -1) {
-                        column.setLength(cc.getLength());
-                    }
-                    if (cc.getPrecision() != -1) {
-                        column.setPrecision(cc.getPrecision());
-                    }
-                    if (cc.getScale() != -1) {
-                        column.setScale(cc.getScale());
-                    }
-                    if(!mappedForm.isUniqueWithinGroup()) {
-                        column.setUnique(cc.isUnique());
-                    }
-                }
-
-                bindColumn(grailsProp, parentProperty, column, cc, path, 
table, sessionFactoryBeanName);
-
-                if (table != null) {
-                    table.addColumn(column);
-                }
-
-                simpleValue.addColumn(column);
-            }
+            var columnConfigToColumnBinder = new ColumnConfigToColumnBinder();
+            ofNullable(propertyConfig)
+                    .map(PropertyConfig::getColumns)
+                    .filter(columns -> !columns.isEmpty())
+                    .orElse(Arrays.asList(new ColumnConfig[] { null }))
+                    .forEach( cc -> {
+                        Column column = new Column();
+                        
columnConfigToColumnBinder.bindColumnConfigToColumn(column,cc,mappedForm);
+                        bindColumn(grailsProp, parentProperty, column, cc, 
path, table, sessionFactoryBeanName);
+                        if (table != null) {
+                            table.addColumn(column);
+                        }
+                        simpleValue.addColumn(column);
+                    });
         }
     }
 
@@ -2966,7 +2935,7 @@ public class GrailsDomainBinder implements 
MetadataContributor {
 
         handleUniqueConstraint(property, column, path, table, columnName, 
sessionFactoryBeanName);
 
-        bindIndex(columnName, column, cc, table);
+        new IndexBinder().bindIndex(columnName, column, cc, table);
 
         final PersistentEntity owner = property.getOwner();
         if (!owner.isRoot()) {
@@ -3017,32 +2986,6 @@ public class GrailsDomainBinder implements 
MetadataContributor {
         table.addUniqueKey(uk);
     }
 
-    private void bindIndex(String columnName, Column column, ColumnConfig cc, 
Table table) {
-        if (cc == null) {
-            return;
-        }
-
-        Object indexObj = cc.getIndex();
-        String indexDefinition = null;
-        if (indexObj instanceof Boolean) {
-            Boolean b = (Boolean) indexObj;
-            if (b) {
-                indexDefinition = table.getName() + '_' + columnName + "_idx";
-            }
-        }
-        else if (indexObj != null) {
-            indexDefinition = indexObj.toString();
-        }
-        if (indexDefinition == null) {
-            return;
-        }
-
-        String[] tokens = indexDefinition.split(",");
-        for (String index : tokens) {
-            table.getOrCreateIndex(index).addColumn(column);
-        }
-    }
-
     private String getColumnNameForPropertyAndPath(PersistentProperty 
grailsProp,
                                                      String path, ColumnConfig 
cc, String sessionFactoryBeanName) {
 
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinder.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinder.java
new file mode 100644
index 0000000000..da654bf363
--- /dev/null
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinder.java
@@ -0,0 +1,26 @@
+package org.grails.orm.hibernate.cfg.domainbinding;
+
+import org.grails.orm.hibernate.cfg.ColumnConfig;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Table;
+import static java.lang.String.format;
+import static java.util.Optional.*;
+
+public class IndexBinder {
+    public void bindIndex(String columnName, Column column, ColumnConfig cc, 
Table table) {
+       ofNullable(cc)
+                .map(ColumnConfig::getIndex)
+                .flatMap(indexObj -> {
+                    if (indexObj instanceof Boolean b) {
+                        return b ? of(format("%s_%s_idx", table.getName(), 
columnName)) : empty();
+                    }
+                    return of(indexObj.toString());
+                })
+                .map(def -> def.split(","))
+                .ifPresent(indices -> {
+                    for (String index : indices) {
+                        table.getOrCreateIndex(index.trim()).addColumn(column);
+                    }
+                });
+    }
+}
diff --git 
a/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinderSpec.groovy
 
b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinderSpec.groovy
new file mode 100644
index 0000000000..6ba548370b
--- /dev/null
+++ 
b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/IndexBinderSpec.groovy
@@ -0,0 +1,90 @@
+package org.grails.orm.hibernate.cfg.domainbinding
+
+import org.grails.orm.hibernate.cfg.ColumnConfig
+import org.hibernate.mapping.Column
+import org.hibernate.mapping.Index
+import org.hibernate.mapping.Table
+import spock.lang.Specification
+
+class IndexBinderSpec extends Specification {
+
+    def indexBinder = new IndexBinder()
+    def table = Mock(Table)
+    def column = Mock(Column)
+    def index = Mock(Index)
+
+    def "should not create index when ColumnConfig is null"() {
+        when:
+        indexBinder.bindIndex("colName", column, null, table)
+
+        then:
+        0 * table._  // verifies no interactions with table
+    }
+
+    def "should create default index when index is true"() {
+        given:
+        def cc = new ColumnConfig()
+        cc.index = true
+        table.getName() >> "test_table"
+
+        when:
+        indexBinder.bindIndex("test_column", column, cc, table)
+
+        then:
+        1 * table.getOrCreateIndex("test_table_test_column_idx") >> index
+        1 * index.addColumn(column)
+    }
+
+    def "should not create index when index is false"() {
+        given:
+        def cc = new ColumnConfig()
+        cc.index = false
+
+        when:
+        indexBinder.bindIndex("test_column", column, cc, table)
+
+        then:
+        0 * table.getOrCreateIndex(_)
+        0 * index.addColumn(_)
+    }
+
+    def "should create multiple indices when comma-separated string is 
provided"() {
+        given:
+        def cc = new ColumnConfig()
+        cc.index = "idx_one,idx_two"
+
+        when:
+        indexBinder.bindIndex("test_column", column, cc, table)
+
+        then:
+        1 * table.getOrCreateIndex("idx_one") >> index
+        1 * table.getOrCreateIndex("idx_two") >> index
+        2 * index.addColumn(column)
+    }
+
+    def "should create single index when string value is provided"() {
+        given:
+        def cc = new ColumnConfig()
+        cc.index = "custom_idx"
+
+        when:
+        indexBinder.bindIndex("test_column", column, cc, table)
+
+        then:
+        1 * table.getOrCreateIndex("custom_idx") >> index
+        1 * index.addColumn(column)
+    }
+
+    def "should not create index when index value is null"() {
+        given:
+        def cc = new ColumnConfig()
+        cc.index = null
+
+        when:
+        indexBinder.bindIndex("test_column", column, cc, table)
+
+        then:
+        0 * table.getOrCreateIndex(_)
+        0 * index.addColumn(_)
+    }
+}
\ No newline at end of file

Reply via email to