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 7eda481ca6c79728c86810a9d978d4c2f6a998ee Author: Walter Duque de Estrada <[email protected]> AuthorDate: Wed Mar 4 08:42:54 2026 -0600 refactor: fold AbstractHibernateGormValidationApi into HibernateGormValidationApi --- grails-data-hibernate7/README.md | 1 - .../AbstractHibernateGormValidationApi.groovy | 167 --------------------- .../hibernate/HibernateGormValidationApi.groovy | 117 +++++++++++++-- .../grails/orm/hibernate/cfg/InstanceProxy.groovy | 6 +- .../hibernate/support/ClosureEventListener.java | 4 +- 5 files changed, 111 insertions(+), 184 deletions(-) diff --git a/grails-data-hibernate7/README.md b/grails-data-hibernate7/README.md index 88a96fc11c..a69562f596 100644 --- a/grails-data-hibernate7/README.md +++ b/grails-data-hibernate7/README.md @@ -31,7 +31,6 @@ These tests live in `grails-datamapping-tck` and are deliberately excluded for H | TCK Spec | # skipped | Skip condition | Reason / notes | |----------|-----------|----------------|------------------------------------------------------------------------------------------------| | `DirtyCheckingSpec` | 6 | `@IgnoreIf(hibernate7.gorm.suite == true)` | Hibernate 7 dirty-checking semantics differ; the entire spec is disabled | -| `NamedQuerySpec` | 38 | `@IgnoreIf(hibernate7.gorm.suite == true)` | Named query support not yet ported to Hibernate 7 | | `GroovyProxySpec` | 5 | `@IgnoreIf(hibernate5/6/7.gorm.suite)` | Groovy proxy support requires `ByteBuddyGroovyProxyFactory`; excluded for all Hibernate suites | | `OptimisticLockingSpec` | 3 | `@IgnoreIf` (detects Hibernate datastore on classpath) | Hibernate has its own `Hibernate7OptimisticLockingSpec` replacement | | `UpdateWithProxyPresentSpec` | 2 | `@IgnoreIf(hibernate7.gorm.suite == true)` | Proxy update behaviour differs in Hibernate 7 | diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormValidationApi.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormValidationApi.groovy deleted file mode 100644 index 4b90b3f9c8..0000000000 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormValidationApi.groovy +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.grails.orm.hibernate - -import groovy.transform.CompileStatic -import org.grails.datastore.gorm.validation.CascadingValidator -import org.grails.datastore.mapping.reflect.ClassUtils -import org.grails.datastore.mapping.validation.ValidationErrors -import org.grails.orm.hibernate.support.HibernateRuntimeUtils -import org.grails.datastore.gorm.GormValidationApi -import org.grails.datastore.mapping.engine.event.ValidationEvent -import org.hibernate.Session -import org.springframework.validation.Errors -import org.springframework.validation.FieldError -import org.springframework.validation.ObjectError -import org.springframework.validation.Validator - -@CompileStatic -abstract class AbstractHibernateGormValidationApi<D> extends GormValidationApi<D> { - - public static final String ARGUMENT_DEEP_VALIDATE = "deepValidate"; - private static final String ARGUMENT_EVICT = "evict"; - - - protected ClassLoader classLoader - protected HibernateDatastore datastore - protected IHibernateTemplate hibernateTemplate - - protected AbstractHibernateGormValidationApi(Class<D> persistentClass, HibernateDatastore datastore, ClassLoader classLoader) { - super(persistentClass, datastore) - this.classLoader = classLoader - this.datastore = datastore - } - - - @Override - boolean validate(D instance, Map arguments = Collections.emptyMap()) { - validate(instance, null, arguments) - } - - boolean validate(D instance, List validatedFieldsList, Map arguments = Collections.emptyMap()) { - Errors errors = setupErrorsProperty(instance); - - Validator validator = getValidator() - if(validator == null) return true - - Boolean valid = Boolean.TRUE - // should evict? - boolean evict = false - boolean deepValidate = true - Set validatedFields = null - if(validatedFieldsList != null) { - validatedFields = new HashSet(validatedFieldsList) - } - - if (arguments?.containsKey(ARGUMENT_DEEP_VALIDATE)) { - deepValidate = ClassUtils.getBooleanFromMap(ARGUMENT_DEEP_VALIDATE, arguments) - } - - evict = ClassUtils.getBooleanFromMap(ARGUMENT_EVICT, arguments); - - fireEvent instance, validatedFieldsList - - - hibernateTemplate.execute { Session session -> - - def previous = readPreviousFlushMode(session) - applyManualFlush(session) - try { - if (validator instanceof CascadingValidator) { - ((CascadingValidator)validator).validate instance, errors, deepValidate - } else if (validator instanceof grails.gorm.validation.CascadingValidator) { - ((grails.gorm.validation.CascadingValidator) validator).validate instance, errors, deepValidate - } else { - validator.validate instance, errors - } - } finally { - if(!errors.hasErrors()) { - restoreFlushMode(session, previous) - } - } - - } - - - int oldErrorCount = errors.errorCount - errors = filterErrors(errors, validatedFields, instance) - - if (errors.hasErrors()) { - valid = Boolean.FALSE - if (evict) { - // if an boolean argument 'true' is passed to the method - // and validation fails then the object will be evicted - // from the session, ensuring it is not saved later when - // flush is called - if (hibernateTemplate.contains(instance)) { - hibernateTemplate.evict(instance) - } - } - } - - // If the errors have been filtered, update the 'errors' object attached to the target. - if (errors.errorCount != oldErrorCount) { - setErrors(instance, errors) - } - - return valid - } - - abstract void restoreFlushMode(Session session, Object previousFlushMode) - - abstract Object readPreviousFlushMode(Session session) - - abstract applyManualFlush(Session session) - - private void fireEvent(Object target, List<?> validatedFieldsList) { - ValidationEvent event = new ValidationEvent(datastore, target); - event.setValidatedFields(validatedFieldsList); - datastore.getApplicationEventPublisher().publishEvent(event); - } - - @SuppressWarnings("rawtypes") - private Errors filterErrors(Errors errors, Set validatedFields, Object target) { - if (validatedFields == null) return errors; - - ValidationErrors result = new ValidationErrors(target); - - final List allErrors = errors.getAllErrors(); - for (Object allError : allErrors) { - ObjectError error = (ObjectError) allError; - - if (error instanceof FieldError) { - FieldError fieldError = (FieldError) error; - if (!validatedFields.contains(fieldError.getField())) continue; - } - - result.addError(error); - } - - return result; - } - - /** - * Initializes the Errors property on target. The target will be assigned a new - * Errors property. If the target contains any binding errors, those binding - * errors will be copied in to the new Errors property. - * - * @param target object to initialize - * @return the new Errors object - */ - protected Errors setupErrorsProperty(Object target) { - HibernateRuntimeUtils.setupErrorsProperty target - } -} diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormValidationApi.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormValidationApi.groovy index d7576cdf44..05e652bf1c 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormValidationApi.groovy +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormValidationApi.groovy @@ -16,31 +16,126 @@ package org.grails.orm.hibernate import groovy.transform.CompileStatic +import org.grails.datastore.gorm.GormValidationApi +import org.grails.datastore.gorm.validation.CascadingValidator +import org.grails.datastore.mapping.reflect.ClassUtils +import org.grails.datastore.mapping.validation.ValidationErrors +import org.grails.datastore.mapping.engine.event.ValidationEvent +import org.grails.orm.hibernate.support.HibernateRuntimeUtils import org.hibernate.FlushMode import org.hibernate.Session +import org.springframework.validation.Errors +import org.springframework.validation.FieldError +import org.springframework.validation.ObjectError +import org.springframework.validation.Validator @CompileStatic -class HibernateGormValidationApi<D> extends AbstractHibernateGormValidationApi<D> { +class HibernateGormValidationApi<D> extends GormValidationApi<D> { + + public static final String ARGUMENT_DEEP_VALIDATE = "deepValidate" + private static final String ARGUMENT_EVICT = "evict" + + protected ClassLoader classLoader + protected HibernateDatastore datastore + protected IHibernateTemplate hibernateTemplate HibernateGormValidationApi(Class<D> persistentClass, HibernateDatastore datastore, ClassLoader classLoader) { - super(persistentClass, datastore, classLoader) + super(persistentClass, datastore) + this.classLoader = classLoader + this.datastore = datastore hibernateTemplate = new GrailsHibernateTemplate(datastore.getSessionFactory(), datastore) } @Override - void restoreFlushMode(Session session, Object previousFlushMode) { - if(previousFlushMode != null) { - session.setHibernateFlushMode((FlushMode)previousFlushMode) + boolean validate(D instance, Map arguments = Collections.emptyMap()) { + validate(instance, null, arguments) + } + + boolean validate(D instance, List validatedFieldsList, Map arguments = Collections.emptyMap()) { + Errors errors = setupErrorsProperty(instance) + + Validator validator = getValidator() + if (validator == null) return true + + Boolean valid = Boolean.TRUE + boolean evict = false + boolean deepValidate = true + Set validatedFields = null + if (validatedFieldsList != null) { + validatedFields = new HashSet(validatedFieldsList) + } + + if (arguments?.containsKey(ARGUMENT_DEEP_VALIDATE)) { + deepValidate = ClassUtils.getBooleanFromMap(ARGUMENT_DEEP_VALIDATE, arguments) + } + + evict = ClassUtils.getBooleanFromMap(ARGUMENT_EVICT, arguments) + + fireEvent(instance, validatedFieldsList) + + hibernateTemplate.execute { Session session -> + FlushMode previous = session.getHibernateFlushMode() + session.setHibernateFlushMode(FlushMode.MANUAL) + try { + if (validator instanceof CascadingValidator) { + ((CascadingValidator) validator).validate instance, errors, deepValidate + } else if (validator instanceof grails.gorm.validation.CascadingValidator) { + ((grails.gorm.validation.CascadingValidator) validator).validate instance, errors, deepValidate + } else { + validator.validate instance, errors + } + } finally { + if (!errors.hasErrors()) { + session.setHibernateFlushMode(previous) + } + } + } + + int oldErrorCount = errors.errorCount + errors = filterErrors(errors, validatedFields, instance) + + if (errors.hasErrors()) { + valid = Boolean.FALSE + if (evict) { + if (hibernateTemplate.contains(instance)) { + hibernateTemplate.evict(instance) + } + } + } + + if (errors.errorCount != oldErrorCount) { + setErrors(instance, errors) } + + return valid } - @Override - Object readPreviousFlushMode(Session session) { - return session.getHibernateFlushMode() + private void fireEvent(Object target, List<?> validatedFieldsList) { + ValidationEvent event = new ValidationEvent(datastore, target) + event.setValidatedFields(validatedFieldsList) + datastore.getApplicationEventPublisher().publishEvent(event) } - @Override - def applyManualFlush(Session session) { - session.setHibernateFlushMode(FlushMode.MANUAL) + @SuppressWarnings("rawtypes") + private Errors filterErrors(Errors errors, Set validatedFields, Object target) { + if (validatedFields == null) return errors + + ValidationErrors result = new ValidationErrors(target) + + final List allErrors = errors.getAllErrors() + for (Object allError : allErrors) { + ObjectError error = (ObjectError) allError + if (error instanceof FieldError) { + FieldError fieldError = (FieldError) error + if (!validatedFields.contains(fieldError.getField())) continue + } + result.addError(error) + } + + return result + } + + protected Errors setupErrorsProperty(Object target) { + HibernateRuntimeUtils.setupErrorsProperty target } } diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/InstanceProxy.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/InstanceProxy.groovy index 3a74b36d12..5a544c0795 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/InstanceProxy.groovy +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/InstanceProxy.groovy @@ -18,17 +18,17 @@ package org.grails.orm.hibernate.cfg import groovy.transform.CompileStatic import org.grails.orm.hibernate.HibernateGormInstanceApi -import org.grails.orm.hibernate.AbstractHibernateGormValidationApi +import org.grails.orm.hibernate.HibernateGormValidationApi @CompileStatic class InstanceProxy { protected instance - protected AbstractHibernateGormValidationApi validateApi + protected HibernateGormValidationApi validateApi protected HibernateGormInstanceApi instanceApi protected final Set<String> validateMethods - InstanceProxy(instance, HibernateGormInstanceApi instanceApi, AbstractHibernateGormValidationApi validateApi) { + InstanceProxy(instance, HibernateGormInstanceApi instanceApi, HibernateGormValidationApi validateApi) { this.instance = instance this.instanceApi = instanceApi this.validateApi = validateApi diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java index b84e36be63..a5f426f050 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/support/ClosureEventListener.java @@ -35,7 +35,7 @@ import org.grails.datastore.mapping.model.config.GormProperties; import org.grails.datastore.mapping.reflect.ClassUtils; import org.grails.datastore.mapping.reflect.EntityReflector; import org.grails.datastore.mapping.validation.ValidationException; -import org.grails.orm.hibernate.AbstractHibernateGormValidationApi; +import org.grails.orm.hibernate.HibernateGormValidationApi; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.Session; @@ -109,7 +109,7 @@ public class ClosureEventListener : failOnError; validateParams = new HashMap(); - validateParams.put(AbstractHibernateGormValidationApi.ARGUMENT_DEEP_VALIDATE, Boolean.FALSE); + validateParams.put(HibernateGormValidationApi.ARGUMENT_DEEP_VALIDATE, Boolean.FALSE); } @Override
