jdaugherty commented on PR #15841:
URL: https://github.com/apache/grails-core/pull/15841#issuecomment-4910950125

   Removing the yakworks library completely revealed a change that's probably 
significant. Here's what AI said: 
   
   I found the root cause. ProfileServiceSpec isn't the real failure — it's 
collateral damage from a genuine behavioral regression in the PR.
   
   The failure chain
   
   1. RegisterSpec.testRegisterAndForgotPassword fails first (the real 
failure). It registers a user, creates a profile, then calls 
ProfileListPage.editProfile(un), which looks up the edit link with the Geb 
selector $('a', text: "User(username:$username)") — matching on the rendered 
toString of the user.
   2. Because RegisterSpec dies at that step, its own cleanup (delete profile, 
delete user at the end of the same feature) never runs, leaving a committed 
extra User and Profile.
   3. That leftover row is exactly why ProfileServiceSpec > test count sees 5 
instead of 4, and why UserSpec > testFindAll (user search results) fails too.
   
   The regression
   
   The profile list GSP renders the association directly: ${entry.user} 
(grails-app/views/profile/index.gsp:52), where profile.user is a lazy Hibernate 
proxy. The User domain has @ToString(includes='username', includeNames=true, 
includePackage=false), so the page used to render User(username:test_user_...).
   
   This PR's new GroovyProxyInterceptorLogic.handleUninitialized() 
(grails-data-hibernate5/.../GroovyProxyInterceptorLogic.java:68-70) 
short-circuits toString() on an uninitialized proxy and returns entityName + 
":" + id — e.g. test.User:5 — without initializing the proxy or calling the 
entity's real toString(). And since HibernateMappingContextConfiguration now 
auto-registers the Groovy-aware proxy factory for every hibernate5 app, the 
spring-security extended app silently switched behavior: the page now renders 
test.User:5, the selector matches nothing, and the spec fails 
deterministically. The behavior is even pinned by the PR's own test 
(GroovyProxyInterceptorLogicSpec asserts "Book:1").
   
   My recommendation
   
   Remove (or rethink) the toString() short-circuit. Rendering 
${someEntity.association} in a GSP is an extremely common pattern in real 
Grails apps, and stock Hibernate semantics — initialize the proxy and delegate 
to the entity's real toString() — is what every existing app depends on. The 
lazy-toString behavior was inherited from yakworks' design, but yakworks was 
opt-in; this factory is now the global default. The id/metaClass/ident() 
interceptions are the valuable part of the fix and don't have this 
compatibility problem.
   
   The concrete change: drop the TO_STRING branch from handleUninitialized in 
the h5 GroovyProxyInterceptorLogic (and the equivalent in h7 if it does the 
same — worth checking GrailsBytecodeProvider/interceptor there), update 
GroovyProxyInterceptorLogicSpec, and add an assertion that toString() 
initializes and returns the real value.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to