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 a4617c9106ffbd108e5f75d3507722c8046c190f
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Mar 7 19:34:41 2026 -0600

    hibernate7: HibernateGormValidationApi bug fix
---
 .../hibernate/HibernateGormValidationApi.groovy    |  14 ++-
 .../HibernateGormValidationApiSpec.groovy          | 121 +++++++++++++++++++++
 2 files changed, 129 insertions(+), 6 deletions(-)

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 2bf204e982..666ab92cba 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
@@ -57,7 +57,7 @@ class HibernateGormValidationApi<D> extends 
GormValidationApi<D> {
         Validator validator = getValidator()
         if (validator == null) return true
 
-        Boolean valid = Boolean.TRUE
+        boolean valid = true
         boolean evict = false
         boolean deepValidate = true
         Set validatedFields = null
@@ -69,7 +69,9 @@ class HibernateGormValidationApi<D> extends 
GormValidationApi<D> {
             deepValidate = 
ClassUtils.getBooleanFromMap(ARGUMENT_DEEP_VALIDATE, arguments)
         }
 
-        evict = ClassUtils.getBooleanFromMap(ARGUMENT_EVICT, arguments)
+        if (arguments?.containsKey(ARGUMENT_EVICT)) {
+            evict = ClassUtils.getBooleanFromMap(ARGUMENT_EVICT, arguments)
+        }
 
         fireEvent(instance, validatedFieldsList)
 
@@ -95,7 +97,7 @@ class HibernateGormValidationApi<D> extends 
GormValidationApi<D> {
         errors = filterErrors(errors, validatedFields, instance)
 
         if (errors.hasErrors()) {
-            valid = Boolean.FALSE
+            valid = false
             if (evict) {
                 if (hibernateTemplate.contains(instance)) {
                     hibernateTemplate.evict(instance)
@@ -116,8 +118,8 @@ class HibernateGormValidationApi<D> extends 
GormValidationApi<D> {
         datastore.getApplicationEventPublisher().publishEvent(event)
     }
 
-    @SuppressWarnings("rawtypes")
-    private Errors filterErrors(Errors errors, Set validatedFields, Object 
target) {
+    @SuppressWarnings('rawtypes')
+    private static Errors filterErrors(Errors errors, Set validatedFields, 
Object target) {
         if (validatedFields == null) return errors
 
         ValidationErrors result = new ValidationErrors(target)
@@ -135,7 +137,7 @@ class HibernateGormValidationApi<D> extends 
GormValidationApi<D> {
         return result
     }
 
-    protected Errors setupErrorsProperty(Object target) {
+    protected static Errors setupErrorsProperty(Object target) {
         HibernateRuntimeUtils.setupErrorsProperty target
     }
 }
diff --git 
a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
new file mode 100644
index 0000000000..f5be2b07ce
--- /dev/null
+++ 
b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateGormValidationApiSpec.groovy
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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
+ *
+ *    https://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 grails.gorm.annotation.Entity
+import grails.gorm.transactions.Rollback
+import org.grails.datastore.mapping.core.DatastoreUtils
+import org.grails.orm.hibernate.cfg.Settings
+import org.springframework.core.env.PropertyResolver
+import org.springframework.transaction.PlatformTransactionManager
+import spock.lang.AutoCleanup
+import spock.lang.Shared
+import spock.lang.Specification
+
+class HibernateGormValidationApiSpec extends Specification {
+
+    @Shared PropertyResolver configuration = 
DatastoreUtils.createPropertyResolver(
+            (Settings.SETTING_DB_CREATE): 'create-drop',
+            'dataSource.url': 
'jdbc:h2:mem:validationApiSpec;LOCK_TIMEOUT=10000'
+    )
+    @Shared @AutoCleanup HibernateDatastore hibernateDatastore = new 
HibernateDatastore(configuration, ValidatedBook)
+    @Shared PlatformTransactionManager transactionManager = 
hibernateDatastore.getTransactionManager()
+
+    @Rollback
+    void "validate returns true (not a boxed Boolean) for a valid instance"() {
+        given:
+        def book = new ValidatedBook(title: 'Clean Code')
+
+        when:
+        def result = book.validate()
+
+        then:
+        result == true
+        result instanceof Boolean
+        !book.hasErrors()
+    }
+
+    @Rollback
+    void "validate returns false for an invalid instance"() {
+        given:
+        def book = new ValidatedBook(title: null)
+
+        when:
+        def result = book.validate()
+
+        then:
+        result == false
+        book.hasErrors()
+        book.errors.getFieldError('title')
+    }
+
+    @Rollback
+    void "validate with evict:false (default) leaves invalid instance in the 
session"() {
+        given:
+        def book = new ValidatedBook(title: 'Valid Title').save(flush: true)
+        book.title = null
+        def session = hibernateDatastore.sessionFactory.currentSession
+
+        when:
+        def result = book.validate(evict: false)
+
+        then:
+        result == false
+        session.contains(book)
+    }
+
+    @Rollback
+    void "validate with evict:true removes invalid instance from the 
session"() {
+        given:
+        def book = new ValidatedBook(title: 'Valid Title').save(flush: true)
+        book.title = null
+        def session = hibernateDatastore.sessionFactory.currentSession
+
+        when:
+        def result = book.validate(evict: true)
+
+        then:
+        result == false
+        !session.contains(book)
+    }
+
+    @Rollback
+    void "validate with specific fields only validates those fields"() {
+        given:
+        def book = new ValidatedBook(title: null, author: null)
+
+        when:
+        def result = book.validate(['author'])
+
+        then:
+        result == true
+        !book.hasErrors()
+    }
+}
+
+@Entity
+class ValidatedBook {
+    String title
+    String author
+
+    static constraints = {
+        title nullable: false
+        author nullable: true
+    }
+}

Reply via email to