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 31e1f796708494efacae79b2c2180e9d9be9790f Author: Walter Duque de Estrada <[email protected]> AuthorDate: Sun Mar 22 13:34:51 2026 -0500 hibernate 7: added more validations for GrailsHibernateUtil --- .../orm/hibernate/cfg/GrailsHibernateUtil.java | 43 +++++----- .../hibernate/cfg/GrailsHibernateUtilSpec.groovy | 91 ++++++++++++++++++---- 2 files changed, 103 insertions(+), 31 deletions(-) diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java index b0643aa3d0..d875267ba2 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtil.java @@ -57,50 +57,56 @@ import org.grails.orm.hibernate.support.HibernateRuntimeUtils; public class GrailsHibernateUtil extends HibernateRuntimeUtils { protected static final Logger LOG = LoggerFactory.getLogger(GrailsHibernateUtil.class); + private static final String VERSION_8_0 = "8.0"; + /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#FETCH_SIZE} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_FETCH_SIZE = HibernateQueryArgument.FETCH_SIZE.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#TIMEOUT} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_TIMEOUT = HibernateQueryArgument.TIMEOUT.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#READ_ONLY} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_READ_ONLY = HibernateQueryArgument.READ_ONLY.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#FLUSH_MODE} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_FLUSH_MODE = HibernateQueryArgument.FLUSH_MODE.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#MAX} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_MAX = HibernateQueryArgument.MAX.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#OFFSET} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_OFFSET = HibernateQueryArgument.OFFSET.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#ORDER} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_ORDER = HibernateQueryArgument.ORDER.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#SORT} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_SORT = HibernateQueryArgument.SORT.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#ORDER_DESC} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ORDER_DESC = HibernateQueryArgument.ORDER_DESC.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#ORDER_ASC} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ORDER_ASC = HibernateQueryArgument.ORDER_ASC.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#FETCH} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_FETCH = HibernateQueryArgument.FETCH.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#IGNORE_CASE} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_IGNORE_CASE = HibernateQueryArgument.IGNORE_CASE.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#CACHE} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_CACHE = HibernateQueryArgument.CACHE.value(); /** @deprecated Use {@link org.grails.orm.hibernate.query.HibernateQueryArgument#LOCK} */ - @Deprecated(since = "8.0", forRemoval = true) + @Deprecated(since = VERSION_8_0, forRemoval = true) public static final String ARGUMENT_LOCK = HibernateQueryArgument.LOCK.value(); - private static final HibernateProxyHandler proxyHandler = new HibernateProxyHandler(); + private static HibernateProxyHandler proxyHandler = new HibernateProxyHandler(); + + public static void setProxyHandler(HibernateProxyHandler handler) { + proxyHandler = handler; + } /** * Sets the target object to read-only using the given SessionFactory instance. This avoids @@ -116,12 +122,13 @@ public class GrailsHibernateUtil extends HibernateRuntimeUtils { if (resource != null) { Session session = sessionFactory.getCurrentSession(); if (canModifyReadWriteState(session, target)) { - if (target instanceof HibernateProxy) { - target = ((HibernateProxy) target) + Object targetToUse = target; + if (targetToUse instanceof HibernateProxy) { + targetToUse = ((HibernateProxy) targetToUse) .getHibernateLazyInitializer() .getImplementation(); } - session.setReadOnly(target, true); + session.setReadOnly(targetToUse, true); session.setHibernateFlushMode(FlushMode.MANUAL); } } diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtilSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtilSpec.groovy index a3e9c390b4..8e319dadf7 100644 --- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtilSpec.groovy +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernateUtilSpec.groovy @@ -20,13 +20,24 @@ package org.grails.orm.hibernate.cfg import grails.gorm.annotation.Entity import grails.gorm.specs.HibernateGormDatastoreSpec -import org.grails.datastore.mapping.model.config.GormProperties +import org.grails.orm.hibernate.proxy.HibernateProxyHandler import org.hibernate.proxy.HibernateProxy -import org.hibernate.proxy.LazyInitializer +import spock.lang.Shared import spock.lang.Unroll class GrailsHibernateUtilSpec extends HibernateGormDatastoreSpec { + @Shared HibernateProxyHandler originalProxyHandler = GrailsHibernateUtil.proxyHandler + HibernateProxyHandler proxyHandlerMock = Mock(HibernateProxyHandler) + + def setup() { + GrailsHibernateUtil.setProxyHandler(proxyHandlerMock) + } + + def cleanup() { + GrailsHibernateUtil.setProxyHandler(originalProxyHandler) + } + @Unroll def "test isDomainClass for #clazz.simpleName"() { expect: @@ -75,25 +86,72 @@ class GrailsHibernateUtilSpec extends HibernateGormDatastoreSpec { !GrailsHibernateUtil.isNotEmpty(null) } - def "test unwrapIfProxy with non-proxy"() { + def "test unwrapIfProxy"() { given: def obj = new Object() + def unwrapped = new Object() - expect: - GrailsHibernateUtil.unwrapIfProxy(obj).is(obj) - GrailsHibernateUtil.unwrapIfProxy(null) == null + when: + def result = GrailsHibernateUtil.unwrapIfProxy(obj) + + then: + 1 * proxyHandlerMock.unwrap(obj) >> unwrapped + result == unwrapped + } + + def "test unwrapProxy"() { + given: + def proxy = Mock(HibernateProxy) + def unwrapped = new Object() + + when: + def result = GrailsHibernateUtil.unwrapProxy(proxy) + + then: + 1 * proxyHandlerMock.unwrap(proxy) >> unwrapped + result == unwrapped + } + + def "test getAssociationProxy and isInitialized"() { + given: + def book = new GHUBook(title: "Carrie") + def proxy = Mock(HibernateProxy) + + when: + def result = GrailsHibernateUtil.getAssociationProxy(book, "title") + def initialized = GrailsHibernateUtil.isInitialized(book, "title") + + then: + 1 * proxyHandlerMock.getAssociationProxy(book, "title") >> proxy + 1 * proxyHandlerMock.isInitialized(book, "title") >> true + result == proxy + initialized } - def "test unwrapIfProxy with EntityProxy"() { + def "test isMappedWithHibernate"() { given: - def implementation = new Object() - def proxy = [ - getTarget: { implementation }, - isInitialized: { true } - ] as org.grails.datastore.mapping.proxy.EntityProxy + def hibernateEntity = Mock(org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity) + def otherEntity = Mock(org.grails.datastore.mapping.model.PersistentEntity) expect: - GrailsHibernateUtil.unwrapIfProxy(proxy).is(implementation) + GrailsHibernateUtil.isMappedWithHibernate(hibernateEntity) + !GrailsHibernateUtil.isMappedWithHibernate(otherEntity) + } + + def "test ensureCorrectGroovyMetaClass"() { + given: + def book = new GHUBook() + def originalMc = book.getMetaClass() + def newMc = GroovySystem.getMetaClassRegistry().getMetaClass(GHUNonDomain) + + when: + GrailsHibernateUtil.ensureCorrectGroovyMetaClass(book, GHUNonDomain) + + then: + book.getMetaClass().getTheClass() == GHUNonDomain + + cleanup: + book.setMetaClass(originalMc) } } @@ -104,6 +162,13 @@ class GHUBook { String title } +@Entity +class GHUAuthor { + Long id + String name + static hasMany = [books: GHUBook] +} + class GHUNonDomain { String name }
