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"() {
