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 375aa5a53cc69e7bfc4822af2904a63264b7eb5e
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Wed Mar 11 22:17:13 2026 -0500

    hibernate 7: CacheConfig usage and include are now enums
---
 .../grails/orm/hibernate/cfg/CacheConfig.groovy    | 122 ++++++++++++++++++++-
 .../org/grails/orm/hibernate/cfg/Mapping.groovy    |   2 +-
 .../RootPersistentClassCommonValuesBinder.java     |   6 +-
 .../hibernate/HibernateMappingBuilder.groovy       |  10 +-
 .../hibernate/HibernateToManyProperty.java         |   3 +-
 .../secondpass/CollectionSecondPassBinder.java     |   2 +-
 .../mapping/HibernateMappingBuilderSpec.groovy     |  14 +--
 .../mapping/HibernateMappingBuilderTests.groovy    |  36 +++---
 .../hibernate/mapping/MappingBuilderSpec.groovy    |   4 +-
 .../orm/hibernate/cfg/PropertyConfigSpec.groovy    |   6 +-
 10 files changed, 160 insertions(+), 45 deletions(-)

diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/CacheConfig.groovy
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/CacheConfig.groovy
index f7da3718ef..0d65058ec2 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/CacheConfig.groovy
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/CacheConfig.groovy
@@ -33,13 +33,103 @@ import org.springframework.validation.DataBinder
 @Builder(builderStrategy = SimpleStrategy, prefix = '')
 class CacheConfig implements Cloneable {
 
-    static final List USAGE_OPTIONS = ['read-only', 'read-write', 
'nonstrict-read-write', 'transactional']
-    static final List INCLUDE_OPTIONS = ['all', 'non-lazy']
+    @AutoClone
+    @CompileStatic
+    static class Usage implements Cloneable {
+        public static final Usage READ_ONLY = new Usage('read-only')
+        public static final Usage READ_WRITE = new Usage('read-write')
+        public static final Usage NONSTRICT_READ_WRITE = new 
Usage('nonstrict-read-write')
+        public static final Usage TRANSACTIONAL = new Usage('transactional')
+
+        private final String value
+
+        Usage(String value) {
+            this.value = value
+        }
+
+        @Override
+        String toString() {
+            return value
+        }
+
+        @Override
+        boolean equals(Object o) {
+            if (this.is(o)) return true
+            if (o == null || getClass() != o.getClass()) return false
+            Usage usage = (Usage) o
+            return value == usage.value
+        }
+
+        @Override
+        int hashCode() {
+            return value != null ? value.hashCode() : 0
+        }
+
+        static List<Usage> values() {
+            [READ_ONLY, READ_WRITE, NONSTRICT_READ_WRITE, TRANSACTIONAL]
+        }
+
+        static Usage of(Object value) {
+            if (value instanceof Usage) return value
+            String str = value?.toString()
+            if (!str) return null
+            Usage found = values().find { it.value.equalsIgnoreCase(str) }
+            if (found) return found
+            return new Usage(str)
+        }
+    }
+
+    @AutoClone
+    @CompileStatic
+    static class Include implements Cloneable {
+        public static final Include ALL = new Include('all')
+        public static final Include NON_LAZY = new Include('non-lazy')
+
+        private final String value
+
+        Include(String value) {
+            this.value = value
+        }
+
+        @Override
+        String toString() {
+            return value
+        }
+
+        @Override
+        boolean equals(Object o) {
+            if (this.is(o)) return true
+            if (o == null || getClass() != o.getClass()) return false
+            Include include = (Include) o
+            return value == include.value
+        }
+
+        @Override
+        int hashCode() {
+            return value != null ? value.hashCode() : 0
+        }
+
+        static List<Include> values() {
+            [ALL, NON_LAZY]
+        }
+
+        static Include of(Object value) {
+            if (value instanceof Include) return value
+            String str = value?.toString()
+            if (!str) return null
+            Include found = values().find { it.value.equalsIgnoreCase(str) }
+            if (found) return found
+            return new Include(str)
+        }
+    }
+
+    static final List<String> USAGE_OPTIONS = Usage.values().collect { 
it.toString() }
+    static final List<String> INCLUDE_OPTIONS = Include.values().collect { 
it.toString() }
 
     /**
      * The cache usage
      */
-    String usage = 'read-write'
+    Usage usage = Usage.READ_WRITE
     /**
      * Whether caching is enabled
      */
@@ -47,7 +137,31 @@ class CacheConfig implements Cloneable {
     /**
      * What to include in caching
      */
-    String include = 'all'
+    Include include = Include.ALL
+
+    void setUsage(Object usage) {
+        Usage u = Usage.of(usage)
+        if (u != null) {
+            this.usage = u
+        }
+    }
+
+    void setInclude(Object include) {
+        Include i = Include.of(include)
+        if (i != null) {
+            this.include = i
+        }
+    }
+
+    CacheConfig usage(Object usage) {
+        setUsage(usage)
+        return this
+    }
+
+    CacheConfig include(Object include) {
+        setInclude(include)
+        return this
+    }
 
     /**
      * Configures a new CacheConfig instance
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
index e4cb7c3d8b..e41bd9d04b 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/Mapping.groovy
@@ -263,7 +263,7 @@ class Mapping extends Entity<PropertyConfig> {
         if (this.cache == null) {
             this.cache = new CacheConfig()
         }
-        this.cache.usage = usage
+        this.cache.usage = CacheConfig.Usage.of(usage)
         this.cache.enabled = true
         return this
     }
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java
index 7cf4f3adb3..34650efda0 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootPersistentClassCommonValuesBinder.java
@@ -70,12 +70,12 @@ public class RootPersistentClassCommonValuesBinder {
         domainClass.configureDerivedProperties();
         CacheConfig cc = gormMapping.getCache();
         if (cc != null && cc.getEnabled()) {
-            root.setCacheConcurrencyStrategy(cc.getUsage());
+            root.setCacheConcurrencyStrategy(cc.getUsage().toString());
             root.setCached(true);
-            if ("read-only".equals(cc.getUsage())) {
+            if ("read-only".equalsIgnoreCase(cc.getUsage().toString())) {
                 root.setMutable(false);
             }
-            
root.setLazyPropertiesCacheable(!"non-lazy".equals(cc.getInclude()));
+            
root.setLazyPropertiesCacheable(!"non-lazy".equalsIgnoreCase(cc.getInclude().toString()));
         }
 
         var schema = domainClass.getSchema(mappings);
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingBuilder.groovy
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingBuilder.groovy
index 8ad9b0fd05..632cec0fe5 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingBuilder.groovy
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernateMappingBuilder.groovy
@@ -188,7 +188,7 @@ class HibernateMappingBuilder implements 
MappingConfigurationBuilder<Mapping, Pr
         if (args.usage) {
             String usage = args.usage.toString()
             if (CacheConfig.USAGE_OPTIONS.contains(usage)) {
-                mapping.cache.usage = usage
+                mapping.cache.usage = CacheConfig.Usage.of(usage)
             } else {
                 LOG.warn("ORM Mapping Invalid: Specified [usage] with value 
[$usage] of [cache] in class [$className] is not valid")
             }
@@ -196,7 +196,7 @@ class HibernateMappingBuilder implements 
MappingConfigurationBuilder<Mapping, Pr
         if (args.include) {
             String include = args.include.toString()
             if (CacheConfig.INCLUDE_OPTIONS.contains(include)) {
-                mapping.cache.include = include
+                mapping.cache.include = CacheConfig.Include.of(include)
             } else {
                 LOG.warn("ORM Mapping Invalid: Specified [include] with value 
[$include] of [cache] in class [$className] is not valid")
             }
@@ -408,16 +408,16 @@ class HibernateMappingBuilder implements 
MappingConfigurationBuilder<Mapping, Pr
             CacheConfig cc = new CacheConfig()
             Object cacheVal = namedArgs.cache
             if (cacheVal instanceof String && 
CacheConfig.USAGE_OPTIONS.contains(cacheVal)) {
-                cc.usage = (String) cacheVal
+                cc.usage = CacheConfig.Usage.of(cacheVal)
                 property.cache = cc
             } else if (cacheVal == true) {
                 property.cache = cc
             } else if (cacheVal instanceof Map) {
                 Map<String, Object> cacheArgs = (Map<String, Object>) cacheVal
                 Object cacheUsage = cacheArgs.usage
-                if (cacheUsage != null) cc.usage = cacheUsage.toString()
+                if (cacheUsage != null) cc.usage = 
CacheConfig.Usage.of(cacheUsage)
                 Object cacheInclude = cacheArgs.include
-                if (cacheInclude != null) cc.include = cacheInclude.toString()
+                if (cacheInclude != null) cc.include = 
CacheConfig.Include.of(cacheInclude)
                 property.cache = cc
             }
         }
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 fdf38abbd4..9c29cbcfb2 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
@@ -62,10 +62,11 @@ public interface HibernateToManyProperty extends 
PropertyWithMapping<PropertyCon
         return getMappedForm().getLazy();
     }
 
-    default String getCacheUSage() {
+    default String getCacheUsage() {
         return Optional.ofNullable(getMappedForm())
                 .map(PropertyConfig::getCache)
                 .map(CacheConfig::getUsage)
+                .map(Object::toString)
                 .orElse(null);
     }
 
diff --git 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java
 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java
index 0b6103cfc3..95033c2820 100644
--- 
a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java
+++ 
b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/secondpass/CollectionSecondPassBinder.java
@@ -80,7 +80,7 @@ public class CollectionSecondPassBinder {
         collection.setSorted(property.isSorted());
 
         collectionKeyColumnUpdater.bind(property, associatedClass, collection);
-        collection.setCacheConcurrencyStrategy(property.getCacheUSage());
+        collection.setCacheConcurrencyStrategy(property.getCacheUsage());
 
         bindCollectionElement(property, mappings, collection);
     }
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderSpec.groovy
index ffded24547..d9bd858484 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderSpec.groovy
@@ -64,8 +64,8 @@ class HibernateMappingBuilderSpec extends Specification {
         Mapping m = evaluate { cache 'read-write', [include: 'all'] }
 
         then:
-        m.cache.usage == 'read-write'
-        m.cache.include == 'all'
+        m.cache.usage.toString() == 'read-write'
+        m.cache.include.toString() == 'all'
     }
 
     def "cache(String) with invalid usage still creates a CacheConfig with the 
default usage"() {
@@ -74,7 +74,7 @@ class HibernateMappingBuilderSpec extends Specification {
 
         then:
         m.cache != null
-        m.cache.usage == 'read-write'  // default preserved; INVALID_USAGE 
rejected
+        m.cache.usage.toString() == 'read-write'  // default preserved; 
INVALID_USAGE rejected
     }
 
     def "cache(Map) with invalid include still creates a CacheConfig with the 
default include"() {
@@ -83,8 +83,8 @@ class HibernateMappingBuilderSpec extends Specification {
 
         then:
         m.cache != null
-        m.cache.usage == 'read-only'
-        m.cache.include == 'all'  // default preserved; INVALID_INCLUDE 
rejected
+        m.cache.usage.toString() == 'read-only'
+        m.cache.include.toString() == 'all'  // default preserved; 
INVALID_INCLUDE rejected
     }
 
     // 
-------------------------------------------------------------------------
@@ -319,8 +319,8 @@ class HibernateMappingBuilderSpec extends Specification {
         Mapping m = evaluate { myProp cache: [usage: 'read-only', include: 
'all'] }
 
         then:
-        m.getPropertyConfig('myProp').cache.usage == 'read-only'
-        m.getPropertyConfig('myProp').cache.include == 'all'
+        m.getPropertyConfig('myProp').cache.usage.toString() == 'read-only'
+        m.getPropertyConfig('myProp').cache.include.toString() == 'all'
     }
 
     def "property column sqlType is set"() {
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderTests.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderTests.groovy
index efa5a72013..ac586e0477 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderTests.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/HibernateMappingBuilderTests.groovy
@@ -465,8 +465,8 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-only', cc.cache.usage
-        assertEquals 'non-lazy', cc.cache.include
+        assertEquals 'read-only', cc.cache.usage.toString()
+        assertEquals 'non-lazy', cc.cache.include.toString()
     }
 
     @Test
@@ -478,8 +478,8 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-only', cc.cache.usage
-        assertEquals 'non-lazy', cc.cache.include
+        assertEquals 'read-only', cc.cache.usage.toString()
+        assertEquals 'non-lazy', cc.cache.include.toString()
     }
 
     @Test
@@ -494,7 +494,7 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-only', cc.cache.usage
+        assertEquals 'read-only', cc.cache.usage.toString()
     }
 
     @Test
@@ -506,7 +506,7 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-only', cc.cache.usage
+        assertEquals 'read-only', cc.cache.usage.toString()
     }
 
     @Test
@@ -521,8 +521,8 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-write', cc.cache.usage
-        assertEquals 'all', cc.cache.include
+        assertEquals 'read-write', cc.cache.usage.toString()
+        assertEquals 'all', cc.cache.include.toString()
     }
 
     @Test
@@ -534,8 +534,8 @@ class HibernateMappingBuilderTests {
         }
 
         def cc = mapping.getPropertyConfig('firstName')
-        assertEquals 'read-write', cc.cache.usage
-        assertEquals 'all', cc.cache.include
+        assertEquals 'read-write', cc.cache.usage.toString()
+        assertEquals 'all', cc.cache.include.toString()
     }
 
     @Test
@@ -556,8 +556,8 @@ class HibernateMappingBuilderTests {
             cache true
         }
 
-        assertEquals 'read-write', mapping.cache.usage
-        assertEquals 'all', mapping.cache.include
+        assertEquals 'read-write', mapping.cache.usage.toString()
+        assertEquals 'all', mapping.cache.include.toString()
     }
 
     @Test
@@ -568,8 +568,8 @@ class HibernateMappingBuilderTests {
             cache usage:'read-only', include:'non-lazy'
         }
 
-        assertEquals 'read-only', mapping.cache.usage
-        assertEquals 'non-lazy', mapping.cache.include
+        assertEquals 'read-only', mapping.cache.usage.toString()
+        assertEquals 'non-lazy', mapping.cache.include.toString()
     }
 
     @Test
@@ -580,8 +580,8 @@ class HibernateMappingBuilderTests {
             cache 'read-only'
         }
 
-        assertEquals 'read-only', mapping.cache.usage
-        assertEquals 'all', mapping.cache.include
+        assertEquals 'read-only', mapping.cache.usage.toString()
+        assertEquals 'all', mapping.cache.include.toString()
     }
 
     @Test
@@ -593,8 +593,8 @@ class HibernateMappingBuilderTests {
         }
 
         // should be ignored and logged to console
-        assertEquals 'read-write', mapping.cache.usage
-        assertEquals 'all', mapping.cache.include
+        assertEquals 'read-write', mapping.cache.usage.toString()
+        assertEquals 'all', mapping.cache.include.toString()
     }
 
     @Test
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/MappingBuilderSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/MappingBuilderSpec.groovy
index 1f4d9902fe..b818dc22a7 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/MappingBuilderSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/grails/gorm/hibernate/mapping/MappingBuilderSpec.groovy
@@ -99,8 +99,8 @@ class MappingBuilderSpec extends Specification {
 
         expect:
         mapping.cache.enabled
-        mapping.cache.usage == 'read'
-        mapping.cache.include == 'some'
+        mapping.cache.usage.toString() == 'read'
+        mapping.cache.include.toString() == 'some'
     }
 
     void "test sort mapping"() {
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/PropertyConfigSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/PropertyConfigSpec.groovy
index ea61d362fa..f372794b28 100644
--- 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/PropertyConfigSpec.groovy
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/PropertyConfigSpec.groovy
@@ -222,7 +222,7 @@ class PropertyConfigSpec extends Specification {
 
         then:
         pc.cache != null
-        pc.cache.usage == 'read-only'
+        pc.cache.usage.toString() == 'read-only'
     }
 
     void "cache(Map) creates and configures a CacheConfig"() {
@@ -234,7 +234,7 @@ class PropertyConfigSpec extends Specification {
 
         then:
         pc.cache != null
-        pc.cache.usage == 'read-write'
+        pc.cache.usage.toString() == 'read-write'
     }
 
     // ─── joinTable 
───────────────────────────────────────────────────────────
@@ -382,7 +382,7 @@ class PropertyConfigSpec extends Specification {
         cloned.cache.usage = 'read-write'
 
         then:
-        pc.cache.usage == 'read-only'
+        pc.cache.usage.toString() == 'read-only'
     }
 
     void "clone copies indexColumn independently"() {

Reply via email to