Skip to content

fix: add Groovy proxy support to HibernateProxyHandler.isInitialized()#15548

Merged
jamesfredley merged 2 commits into8.0.x-hibernate7from
fix/groovy-proxy-isinitialized
Apr 3, 2026
Merged

fix: add Groovy proxy support to HibernateProxyHandler.isInitialized()#15548
jamesfredley merged 2 commits into8.0.x-hibernate7from
fix/groovy-proxy-isinitialized

Conversation

@jamesfredley
Copy link
Copy Markdown
Contributor

Summary

  • Bug: HibernateProxyHandler.isInitialized() in Hibernate 7 was missing Groovy proxy support, causing uninitialized Groovy proxies to be incorrectly reported as initialized. The fallback Hibernate.isInitialized() returns true for any non-Hibernate object, masking the bug.
  • Fix: Add GroovyProxyInterceptorLogic.isInitialized() helper that checks ProxyInstanceMetaClass.isProxyInitiated(), and invoke it from HibernateProxyHandler.isInitialized() before the Hibernate fallback.
  • Parity: The Hibernate 5 implementation already had this check. This restores behavioral parity with Hibernate 5.

Changes

File Change
GroovyProxyInterceptorLogic.java Add isInitialized(Object) static helper method
HibernateProxyHandler.java Call GroovyProxyInterceptorLogic.isInitialized() before Hibernate.isInitialized() fallback
HibernateProxyHandler7Spec.groovy Add test: "test isInitialized for a Groovy proxy before initialization"

Testing

All 21 HibernateProxyHandler7Spec tests pass, including the new Groovy proxy isInitialized test.

The Hibernate 7 HibernateProxyHandler.isInitialized() was missing a check
for Groovy proxies (ProxyInstanceMetaClass), causing uninitialized Groovy
proxies to be incorrectly reported as initialized. This is because the
fallback Hibernate.isInitialized() returns true for any non-Hibernate
object.

Add GroovyProxyInterceptorLogic.isInitialized() helper that checks
ProxyInstanceMetaClass.isProxyInitiated(), and call it from
HibernateProxyHandler.isInitialized() before the Hibernate fallback.

The Hibernate 5 implementation already had this check. This restores
parity and adds the corresponding test.

Assisted-by: OpenCode <opencode@opencode.ai>
Copilot AI review requested due to automatic review settings April 2, 2026 15:40
@jamesfredley jamesfredley self-assigned this Apr 2, 2026
@jamesfredley jamesfredley moved this to In Progress in Apache Grails Apr 2, 2026
@jamesfredley jamesfredley added this to the grails:8.0.0-M1 milestone Apr 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Groovy proxy awareness to HibernateProxyHandler.isInitialized() in Hibernate 7 to prevent uninitialized Groovy proxies from being incorrectly reported as initialized, restoring behavior parity with Hibernate 5.

Changes:

  • Added GroovyProxyInterceptorLogic.isInitialized(Object) tri-state helper for Groovy proxies.
  • Updated HibernateProxyHandler.isInitialized() to consult Groovy proxy state before falling back to Hibernate.isInitialized().
  • Added a new spec verifying isInitialized returns false for an uninitialized Groovy proxy.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyProxyInterceptorLogic.java Adds Groovy-proxy initialization detection helper.
grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/HibernateProxyHandler.java Uses the Groovy-proxy helper prior to Hibernate fallback.
grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/proxy/HibernateProxyHandler7Spec.groovy Adds regression test for uninitialized Groovy proxy initialization reporting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Rename groovyProxyInit to groovyProxyInitialized for clearer state semantics
- Add ProxyInstanceMetaClass precondition assertion in Groovy proxy test

Assisted-by: OpenCode <opencode@opencode.ai>
@testlens-app
Copy link
Copy Markdown

testlens-app Bot commented Apr 2, 2026

✅ All tests passed ✅

🏷️ Commit: 148d718
▶️ Tests: 32256 executed
⚪️ Checks: 30/30 completed


Learn more about TestLens at testlens.app.

Copy link
Copy Markdown
Contributor

@jdaugherty jdaugherty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, historically GroovyProxies were not used in hibernate. A different proxy mechanism was used. Was this a change with the hibernate 7 implementation? (see GroovyProxySpec for history)

@jamesfredley
Copy link
Copy Markdown
Contributor Author

@jdaugherty

You're right - Groovy proxies (GroovyProxyFactory/ProxyInstanceMetaClass) are not the default proxy mechanism for Hibernate. The TCK GroovyProxySpec is @IgnoreIf for both H5 and H7 with the comment: "this test is ignored because Groovy proxies are not used with Hibernate".

Hibernate uses its own proxy mechanism (ByteBuddy/Javassist HibernateProxy instances). H7's ByteBuddyGroovyProxyFactory creates Hibernate proxies enhanced with Groovy-aware interception - these are NOT "Groovy proxies" in the GroovyProxyFactory sense.

However, H5's HibernateProxyHandler.isInitialized() already had a defensive ProxyInstanceMetaClass check (here) to handle the edge case where someone overrides the proxyFactory (as Hibernate7GroovyProxySpec demonstrates by manually setting proxyFactory = new GroovyProxyFactory()). Without this check, Hibernate.isInitialized() returns true for any non-HibernateProxy object - silently giving wrong answers for Groovy proxies.

This PR restores that same defensive behavior in H7's handler for parity.

Copy link
Copy Markdown
Member

@borinquenkid borinquenkid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems correct to me

@jamesfredley jamesfredley merged commit 6cc9fda into 8.0.x-hibernate7 Apr 3, 2026
30 checks passed
@jamesfredley jamesfredley deleted the fix/groovy-proxy-isinitialized branch April 3, 2026 21:46
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Apache Grails Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants