This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch merge-hibernate6 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit e4614dc9f6a486d0e64d7b9760ae3827ca0982e7 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Tue Aug 12 13:00:12 2025 -0500 ByteBuddy adjustment --- .../gorm/specs/proxy/ByteBuddyProxySpec.groovy | 195 ++++++++------------- .../core/GrailsDataHibernate6TckManager.groovy | 1 + 2 files changed, 74 insertions(+), 122 deletions(-) diff --git a/grails-data-hibernate6/core/src/test/groovy/grails/gorm/specs/proxy/ByteBuddyProxySpec.groovy b/grails-data-hibernate6/core/src/test/groovy/grails/gorm/specs/proxy/ByteBuddyProxySpec.groovy index 8dd3b03114..e0a80451e7 100644 --- a/grails-data-hibernate6/core/src/test/groovy/grails/gorm/specs/proxy/ByteBuddyProxySpec.groovy +++ b/grails-data-hibernate6/core/src/test/groovy/grails/gorm/specs/proxy/ByteBuddyProxySpec.groovy @@ -1,154 +1,105 @@ -/* - * 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 grails.gorm.specs.proxy -import grails.gorm.specs.entities.Club -import grails.gorm.specs.entities.Team -import org.apache.grails.data.hibernate6.core.GrailsDataHibernate6TckManager -import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec -import org.grails.datastore.mapping.reflect.ClassUtils -import org.grails.orm.hibernate.proxy.HibernateProxyHandler -import spock.lang.PendingFeatureIf +import grails.gorm.specs.HibernateGormDatastoreSpec +import grails.persistence.Entity +import groovy.transform.CompileStatic +import org.grails.datastore.mapping.proxy.ProxyHandler +import org.grails.orm.hibernate.HibernateDatastore +import org.hibernate.proxy.HibernateProxy import spock.lang.Shared +import spock.lang.Specification /** - * Contains misc proxy tests using Hibernate defaults, which is ByteBuddy. - * These should all be passing for Gorm to be operating correctly with Groovy. + * Test cases for ByteBuddy proxy handling */ -// TODO: are we still supporting proxies? -class ByteBuddyProxySpec extends GrailsDataTckSpec<GrailsDataHibernate6TckManager> { +class ByteBuddyProxySpec extends HibernateGormDatastoreSpec { + void setupSpec() { - manager.addAllDomainClasses([Team, Club]) + manager.addAllDomainClasses([ByteBuddyClub, ByteBuddyTeam, ByteBuddyPlayer]) } - @Shared - HibernateProxyHandler proxyHandler = new HibernateProxyHandler() + void "Test that accessing id on a proxy does not initialize it"() { + given: + def club = new ByteBuddyClub(name: "The Club").save(flush: true) + def team = new ByteBuddyTeam(name: "A-Team", club: club).save(flush: true) + session.clear() - //to show test that fail that should succeed set this to true. or uncomment the - // testImplementation "org.yakworks:hibernate-groovy-proxy:$yakworksHibernateGroovyProxy" to see pass - boolean runPending = ClassUtils.isPresent("yakworks.hibernate.proxy.ByteBuddyGroovyInterceptor") - - Team createATeam(){ - Club c = new Club(name: "DOOM Club").save(failOnError:true) - Team team = new Team(name: "The A-Team", club: c).save(failOnError:true, flush:true) - return team - } - -// @Ignore("StaticTestUtil.team_id_asserts assert !Hibernate.isInitialized(team) fails") - void "getId and id property checks dont initialize proxy if in a CompileStatic method"() { when: - Team team = createATeam() - manager.session.clear() - //TODO load is broken -// team = Team.load(team.id) - team = Team.list().find { it.id == team.id } - - then:"The asserts on getId and id should not initialize proxy when statically compiled" - StaticTestUtil.team_id_asserts(team) - !proxyHandler.isInitialized(team) - - StaticTestUtil.club_id_asserts(team) - !proxyHandler.isInitialized(team.club) - } - - @PendingFeatureIf({ !instance.runPending }) - void "getId and id dont initialize proxy"() { - when:"load proxy" - Team team = createATeam() - manager.session.clear() - team = Team.load(team.id) - - then:"The asserts on getId and id should not initialize proxy" - proxyHandler.isProxy(team) - team.getId() - !proxyHandler.isInitialized(team) + team = ByteBuddyTeam.load(team.id) + def proxyHandler = manager.hibernateDatastore.mappingContext.proxyHandler - team.id + then: + "Dynamic Groovy access does not initialize the proxy" !proxyHandler.isInitialized(team) - - and: "the getAt check for id should not initialize" - team['id'] + team.id != null !proxyHandler.isInitialized(team) - } - @PendingFeatureIf({ !instance.runPending }) - void "truthy check on instance should not initialize proxy"() { - when:"load proxy" - Team team = createATeam() - manager.session.clear() - team = Team.load(team.id) - then:"The asserts on the intance should not init proxy" - team - !proxyHandler.isInitialized(team) - - and: "truthy check on association should not initialize" - team.club - !proxyHandler.isInitialized(team.club) } - @PendingFeatureIf({ !instance.runPending }) - void "id checks on association should not initialize its proxy"() { - when:"load instance" - Team team = createATeam() - manager.session.clear() - team = Team.load(team.id) + void "Test that accessing a lazy association returns an uninitialized proxy"() { + given: + def club = new ByteBuddyClub(name: "The Club").save(flush: true) + def team = new ByteBuddyTeam(name: "A-Team", club: club).save(flush: true) + session.clear() - then:"The asserts on the intance should not init proxy" - !proxyHandler.isInitialized(team.club) + when: + team = ByteBuddyTeam.load(team.id) + def proxyHandler = manager.hibernateDatastore.mappingContext.proxyHandler + proxyHandler.initialize(team) + def clubProxy = team.club - team.club.getId() - !proxyHandler.isInitialized(team.club) + then: + "The association is a proxy" + assert_is_proxy(clubProxy) - team.club.id - !proxyHandler.isInitialized(team.club) + and: "The association proxy is not initialized" + !proxyHandler.isInitialized(clubProxy) - team.clubId - !proxyHandler.isInitialized(team.club) - and: "the getAt check for id should not initialize" - team.club['id'] - !proxyHandler.isInitialized(team.club) } - void "isDirty should not intialize the association proxy"() { - when:"load instance" - Team team = createATeam() - manager.session.clear() - team = Team.load(team.id) + private void assert_id_without_init(ProxyHandler handler, Object proxy) { + assert handler.getIdentifier(proxy) != null + assert !handler.isInitialized(proxy) + } - then:"The asserts on the intance should not init proxy" - !proxyHandler.isInitialized(team) + private void assert_is_proxy(Object proxy) { + assert (proxy instanceof HibernateProxy) + } - //isDirty will init the proxy. should make changes for this. - !team.isDirty() - proxyHandler.isInitialized(team) - //it should not have initialized the association - !proxyHandler.isInitialized(team.club) +} - when: "its made dirty" - team.name = "B-Team" +@Entity +class ByteBuddyClub { + Long id + String name + static mapping = { + id generator: 'native' + version false + } +} - then: - team.isDirty() - //still should not have initialized it. - !proxyHandler.isInitialized(team.club) +@Entity +class ByteBuddyTeam { + Long id + String name + ByteBuddyClub club + + static hasMany = [players: ByteBuddyPlayer] + static mapping = { + id generator: 'native' + version false + club lazy: true } +} +@Entity +class ByteBuddyPlayer { + Long id + String name + static mapping = { + id generator: 'native' + version false + } } diff --git a/grails-data-hibernate6/core/src/test/groovy/org/apache/grails/data/hibernate6/core/GrailsDataHibernate6TckManager.groovy b/grails-data-hibernate6/core/src/test/groovy/org/apache/grails/data/hibernate6/core/GrailsDataHibernate6TckManager.groovy index 2aeb46d4d1..5d278f88bd 100644 --- a/grails-data-hibernate6/core/src/test/groovy/org/apache/grails/data/hibernate6/core/GrailsDataHibernate6TckManager.groovy +++ b/grails-data-hibernate6/core/src/test/groovy/org/apache/grails/data/hibernate6/core/GrailsDataHibernate6TckManager.groovy @@ -62,6 +62,7 @@ class GrailsDataHibernate6TckManager extends GrailsDataTckManager { System.setProperty('hibernate6.gorm.suite', "true") grailsApplication = new DefaultGrailsApplication(domainClasses as Class[], new GroovyClassLoader(GrailsDataHibernate6TckManager.getClassLoader())) grailsConfig.dataSource.dbCreate = "create-drop" + grailsConfig.hibernate.proxy_factory_class = "yakworks.hibernate.proxy.ByteBuddyGroovyProxyFactory" if (grailsConfig) { grailsApplication.config.putAll(grailsConfig) }
