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/01/13 18:50:24 UTC
(grails-core) 12/13: Refactor GrailsDomainBinder.isSaveUpdateCascade to use CascadeBehavior enum and add tests
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch 8.0.x-hibernate7
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit a5f1c7035cc194d6efac33a26ef3bc9efeeb0212
Author: Walter B Duque de Estrada <bo...@users.noreply.github.com>
AuthorDate: Mon Jan 12 11:48:55 2026 -0600
Refactor GrailsDomainBinder.isSaveUpdateCascade to use CascadeBehavior enum and add tests
---
.../orm/hibernate/cfg/GrailsDomainBinder.java | 30 +++-------
.../cfg/domainbinding/CascadeBehavior.java | 4 ++
.../hibernate/cfg/GrailsDomainBinderSpec.groovy | 65 ++++++++++++++++++++--
.../domainbinding/CascadeBehaviorEnumSpec.groovy | 51 +++++++++++++++++
4 files changed, 122 insertions(+), 28 deletions(-)
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
index 41b348dfb7..fdc4dab58f 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java
@@ -51,11 +51,8 @@ import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.engine.OptimisticLockStyle;
-import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.FilterDefinition;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.mapping.Backref;
import org.hibernate.mapping.Bag;
import org.hibernate.mapping.BasicValue;
@@ -88,7 +85,6 @@ import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.usertype.UserCollectionType;
-import org.jboss.jandex.IndexView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
@@ -101,7 +97,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
@@ -122,22 +117,15 @@ public class GrailsDomainBinder
implements AdditionalMappingContributor, TypeContributor
{
- private static final String CASCADE_ALL_DELETE_ORPHAN = CascadeBehavior.ALL_DELETE_ORPHAN.getValue();
public static final String FOREIGN_KEY_SUFFIX = "_id";
private static final String STRING_TYPE = "string";
private static final String EMPTY_PATH = "";
public static final char UNDERSCORE = '_';
- public static final String CASCADE_ALL = CascadeBehavior.ALL.getValue();
- public static final String CASCADE_SAVE_UPDATE = CascadeBehavior.SAVE_UPDATE.getValue();
- public static final String CASCADE_NONE = CascadeBehavior.NONE.getValue();
public static final String BACKTICK = "`";
public static final String ENUM_TYPE_CLASS = org.grails.orm.hibernate.HibernateLegacyEnumType.class.getName();
public static final String ENUM_CLASS_PROP = "enumClass";
- private static final String ENUM_TYPE_PROP = "type";
- public static final String DEFAULT_ENUM_TYPE = "default";
private static final Logger LOG = LoggerFactory.getLogger(GrailsDomainBinder.class);
- public static final String SEQUENCE_KEY = "sequence";
@@ -146,7 +134,6 @@ public class GrailsDomainBinder
*/
private static final NamingStrategyProvider NAMING_STRATEGY_PROVIDER = new NamingStrategyProvider();
public static final String JPA_DEFAULT_DISCRIMINATOR_TYPE = "DTYPE";
- public static final String IDENTIFIER_NORMALIZER = "identifier_normalizer";
private final CollectionType CT = new CollectionType(null, this) {
public Collection create(ToMany property, PersistentClass owner, String path, InFlightMetadataCollector mappings, String sessionFactoryBeanName) {
@@ -1029,7 +1016,7 @@ public class GrailsDomainBinder
}
if (pc.getCascade() != null) {
- collection.setOrphanDelete(pc.getCascade().equals(CASCADE_ALL_DELETE_ORPHAN));
+ collection.setOrphanDelete(pc.getCascade().equals(CascadeBehavior.ALL_DELETE_ORPHAN.getValue()));
}
// if it's a one-to-many mapping
if (shouldBindCollectionWithForeignKey(property)) {
@@ -1170,18 +1157,17 @@ public class GrailsDomainBinder
* @param cascade The string containing the cascade properties.
* @return True if save-update or any other cascade property that encompasses those is present.
*/
- private boolean isSaveUpdateCascade(String cascade) {
- if (CASCADE_SAVE_UPDATE.equals(cascade) || "save-update".equals(cascade)) {
- return true;
- }
-
+ protected boolean isSaveUpdateCascade(String cascade) {
String[] cascades = cascade.split(",");
for (String cascadeProp : cascades) {
String trimmedProp = cascadeProp.trim();
-
- if (CASCADE_ALL.equals(trimmedProp) || CASCADE_ALL_DELETE_ORPHAN.equals(trimmedProp) || "save-update".equals(trimmedProp)) {
- return true;
+ try {
+ if (CascadeBehavior.fromString(trimmedProp).isSaveUpdate()) {
+ return true;
+ }
+ } catch (MappingException e) {
+ // ignore
}
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehavior.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehavior.java
index afba75ea74..f4a0cf70d3 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehavior.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehavior.java
@@ -71,6 +71,10 @@ public enum CascadeBehavior {
return value;
}
+ public boolean isSaveUpdate() {
+ return this == ALL || this == ALL_DELETE_ORPHAN || this == SAVE_UPDATE;
+ }
+
public static CascadeBehavior fromString(String value) {
return Arrays.stream(CascadeBehavior.values())
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinderSpec.groovy
index 0c07c13bed..048eb86ae2 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinderSpec.groovy
@@ -14,11 +14,64 @@ class GrailsDomainBinderSpec extends HibernateGormDatastoreSpec {
def fieldProperties = [title: String]
def persistentEntity = createPersistentEntity(grailsDomainBinder,simpleName, fieldProperties, [:])
- grailsDomainBinder.bindRoot(persistentEntity, collector,"sessionFactoryName")
- println("when")
- then:
- 1 == 1
- }
+ grailsDomainBinder.bindRoot(persistentEntity, collector,"sessionFactoryName")
+ println("when")
-}
\ No newline at end of file
+ then:
+
+ 1 == 1
+
+ }
+
+
+
+ void "Test isSaveUpdateCascade"() {
+
+ given:
+
+ def binder = getGrailsDomainBinder()
+
+
+
+ expect:
+
+ binder.isSaveUpdateCascade(cascade) == expected
+
+
+
+ where:
+
+ cascade | expected
+
+ "all" | true
+
+ "all-delete-orphan" | true
+
+ "persist,merge" | true
+
+ "save-update" | true
+
+ "merge,persist" | true
+
+ "merge" | false
+
+ "persist" | false
+
+ "none" | false
+
+ "delete" | false
+
+ "lock" | false
+
+ "evict" | false
+
+ "replicate" | false
+
+ "all,delete" | true
+
+ "persist,merge,lock" | true
+
+ }
+
+ }
\ No newline at end of file
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorEnumSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorEnumSpec.groovy
new file mode 100644
index 0000000000..4c95090b89
--- /dev/null
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/CascadeBehaviorEnumSpec.groovy
@@ -0,0 +1,51 @@
+package org.grails.orm.hibernate.cfg.domainbinding
+
+import org.hibernate.MappingException
+import spock.lang.Specification
+import spock.lang.Unroll
+
+class CascadeBehaviorEnumSpec extends Specification {
+
+ @Unroll
+ void "test isSaveUpdate for #behavior"() {
+ expect:
+ behavior.isSaveUpdate() == expected
+
+ where:
+ behavior | expected
+ CascadeBehavior.ALL | true
+ CascadeBehavior.ALL_DELETE_ORPHAN | true
+ CascadeBehavior.SAVE_UPDATE | true
+ CascadeBehavior.MERGE | false
+ CascadeBehavior.PERSIST | false
+ CascadeBehavior.DELETE | false
+ CascadeBehavior.LOCK | false
+ CascadeBehavior.EVICT | false
+ CascadeBehavior.REPLICATE | false
+ CascadeBehavior.NONE | false
+ }
+
+ @Unroll
+ void "test fromString for #value"() {
+ expect:
+ CascadeBehavior.fromString(value) == expected
+
+ where:
+ value | expected
+ "all" | CascadeBehavior.ALL
+ "all-delete-orphan" | CascadeBehavior.ALL_DELETE_ORPHAN
+ "save-update" | CascadeBehavior.SAVE_UPDATE
+ "persist,merge" | CascadeBehavior.SAVE_UPDATE
+ "merge" | CascadeBehavior.MERGE
+ "persist" | CascadeBehavior.PERSIST
+ "none" | CascadeBehavior.NONE
+ }
+
+ void "test fromString with invalid value"() {
+ when:
+ CascadeBehavior.fromString("invalid")
+
+ then:
+ thrown(MappingException)
+ }
+}