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 760d8736153f3aa281c4435af85785e87d973b5e
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sun Jul 13 13:32:17 2025 -0500

    refactor StringColumnConstraintsBinder
---
 .../orm/hibernate/cfg/GrailsDomainBinder.java      |  54 +++-------
 .../StringColumnConstraintsBinder.java             |  39 +++++++
 .../StringColumnConstraintsBinderSpec.groovy       | 116 +++++++++++++++++++++
 3 files changed, 167 insertions(+), 42 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 db87d77c68..af40c7ed71 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
@@ -40,6 +40,7 @@ import 
org.grails.orm.hibernate.cfg.domainbinding.ConfigureDerivedPropertiesCons
 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.StringColumnConstraintsBinder;
 import org.grails.orm.hibernate.cfg.domainbinding.TypeNameProvider;
 import org.hibernate.FetchMode;
 import org.hibernate.MappingException;
@@ -2809,11 +2810,16 @@ public class GrailsDomainBinder implements 
MetadataContributor {
         bindSimpleValue(grailsProp, null, simpleValue, path, propertyConfig, 
sessionFactoryBeanName);
     }
 
-    private void bindSimpleValue(PersistentProperty grailsProp,
-                                   PersistentProperty parentProperty, 
SimpleValue simpleValue,
-                                   String path, PropertyConfig propertyConfig, 
String sessionFactoryBeanName) {
+    private void bindSimpleValue(
+            PersistentProperty grailsProp
+            , PersistentProperty parentProperty
+            , SimpleValue simpleValue
+            , String path
+            , PropertyConfig propertyConfig
+            , String sessionFactoryBeanName
+    ) {
         setTypeForPropertyConfig(grailsProp, simpleValue, propertyConfig);
-        final PropertyConfig mappedForm = (PropertyConfig) 
grailsProp.getMapping().getMappedForm();
+        final PropertyConfig mappedForm = (PropertyConfig) 
grailsProp.getMappedForm();
         if (mappedForm != null && mappedForm.isDerived() && !(grailsProp 
instanceof TenantId)) {
             Formula formula = new Formula();
             formula.setFormula(propertyConfig.getFormula());
@@ -2925,7 +2931,8 @@ public class GrailsDomainBinder implements 
MetadataContributor {
             // Use the constraints for this property to more accurately define
             // the column's length, precision, and scale
             if (String.class.isAssignableFrom(property.getType()) || 
byte[].class.isAssignableFrom(property.getType())) {
-                bindStringColumnConstraints(column, property);
+                final org.grails.datastore.mapping.config.Property mappedForm 
= getPropertyConfig(property);
+                new 
StringColumnConstraintsBinder().bindStringColumnConstraints(column, mappedForm);
             }
 
             if (Number.class.isAssignableFrom(property.getType())) {
@@ -3120,29 +3127,6 @@ public class GrailsDomainBinder implements 
MetadataContributor {
     }
 
 
-
-    /**
-     * Interrogates the specified constraints looking for any constraints that 
would limit the
-     * length of the property's value.  If such constraints exist, this method 
adjusts the length
-     * of the column accordingly.
-     *  @param column              the column that corresponds to the property
-     * @param constrainedProperty the property's constraints
-     */
-    private void bindStringColumnConstraints(Column column, PersistentProperty 
constrainedProperty) {
-        final org.grails.datastore.mapping.config.Property mappedForm = 
getPropertyConfig(constrainedProperty);
-        Number columnLength = mappedForm.getMaxSize();
-        List<?> inListValues = mappedForm.getInList();
-        if (columnLength != null) {
-            column.setLength(columnLength.intValue());
-        } else if (inListValues != null) {
-            column.setLength(getMaxSize(inListValues));
-        }
-    }
-
-    private void bindNumericColumnConstraints(Column column, 
PersistentProperty constrainedProperty) {
-        bindNumericColumnConstraints(column, constrainedProperty, null);
-    }
-
     /**
      * Interrogates the specified constraints looking for any constraints that 
would limit the
      * precision and/or scale of the property's value.  If such constraints 
exist, this method adjusts
@@ -3214,20 +3198,6 @@ public class GrailsDomainBinder implements 
MetadataContributor {
         return numDigits;
     }
 
-    /**
-     * @return the maximum length of the strings in the specified list
-     */
-    private int getMaxSize(List<?> inListValues) {
-        int maxSize = 0;
-
-        for (Object inListValue : inListValues) {
-            String value = (String) inListValue;
-            maxSize = Math.max(value.length(), maxSize);
-        }
-
-        return maxSize;
-    }
-
     private void handleUniqueConstraint(PersistentProperty property, Column 
column, String path, Table table, String columnName, String 
sessionFactoryBeanName) {
         final PropertyConfig mappedForm = getPropertyConfig(property);
         if (mappedForm.isUnique()) {
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinder.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinder.java
new file mode 100644
index 0000000000..ded0a91ace
--- /dev/null
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinder.java
@@ -0,0 +1,39 @@
+package org.grails.orm.hibernate.cfg.domainbinding;
+
+import org.grails.datastore.mapping.config.Property;
+import org.hibernate.mapping.Column;
+
+import java.util.Objects;
+import java.util.Optional;
+
+public class StringColumnConstraintsBinder {
+
+
+    public void bindStringColumnConstraints(Column column, Property 
mappedForm) {
+        Integer number = Optional.ofNullable(mappedForm.getMaxSize())
+                .map(Number::intValue)
+                .orElse(
+                        getMax(mappedForm).orElse(0)
+                );
+        if (number > 0) {
+            column.setLength(number);
+        }
+
+    }
+
+    private  Optional<Integer> getMax(Property mappedForm) {
+        return Optional.ofNullable(mappedForm.getInList())
+                .flatMap(list -> list.stream()
+                .map(this::parseInt)
+                .filter(Objects::nonNull)
+                .reduce(Integer::max));
+    }
+
+    private Integer parseInt(String value) {
+        try{
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+}
diff --git 
a/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinderSpec.groovy
 
b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinderSpec.groovy
new file mode 100644
index 0000000000..45877c9cc1
--- /dev/null
+++ 
b/grails-data-hibernate6/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/StringColumnConstraintsBinderSpec.groovy
@@ -0,0 +1,116 @@
+package org.grails.orm.hibernate.cfg.domainbinding
+
+import org.hibernate.mapping.Column
+import org.grails.datastore.mapping.config.Property
+import spock.lang.Specification
+
+class StringColumnConstraintsBinderSpec extends Specification {
+
+    StringColumnConstraintsBinder binder
+    Column column
+    Property mappedForm
+
+    def setup() {
+        binder = new StringColumnConstraintsBinder()
+        column = Mock(Column)
+        mappedForm = Mock(Property)
+    }
+
+    def "should not set column length when neither is provided"() {
+        given:
+        mappedForm.getMaxSize() >> null
+        mappedForm.getInList() >> null
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        0 * column.setLength(_)
+    }
+
+    def "should not set column length when empty list"() {
+        given:
+        mappedForm.getMaxSize() >> null
+        mappedForm.getInList() >> []
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        0 * column.setLength(_)
+    }
+
+    def "should set column length when maxSize is provided"() {
+        given:
+        mappedForm.getMaxSize() >> 255
+        mappedForm.getInList() >> null
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        1 * column.setLength(255)
+    }
+
+    def "should set column length to longest inList value when maxSize is 
null"() {
+        given:
+        mappedForm.getMaxSize() >> null
+        mappedForm.getInList() >> ["1","2","3","4"]
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        1 * column.setLength(4) // length of "very long string"
+    }
+
+    def "should set column length to longest valid int inList value when 
maxSize is null"() {
+        given:
+        mappedForm.getMaxSize() >> null
+        mappedForm.getInList() >> ["4","string",Long.MAX_VALUE.toString(), 
null]
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        1 * column.setLength(4) // length of "very long string"
+    }
+
+
+    def "should prioritize maxSize over inList when both are present"() {
+        given:
+        mappedForm.getMaxSize() >> 1
+        mappedForm.getInList() >> ["3"]
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        1 * column.setLength(1)
+    }
+
+    def "should handle zero maxSize"() {
+        given:
+        mappedForm.getMaxSize() >> 0
+        mappedForm.getInList() >> null
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        0 * column.setLength(_)
+    }
+
+
+    def "should handle Number subclasses for maxSize"() {
+        given:
+        mappedForm.getMaxSize() >> 50L // Long instead of Integer
+        mappedForm.getInList() >> null
+
+        when:
+        binder.bindStringColumnConstraints(column, mappedForm)
+
+        then:
+        1 * column.setLength(50)
+    }
+}
\ No newline at end of file

Reply via email to