cglib proxy doesn't ensure java identity within a session
---------------------------------------------------------
Key: HHH-2466
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2466
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.2
Reporter: Stephen Haberman
Because CGLIBLazyInitializer uses composition instead of inheritance, there are two object
instances (one for the proxy, one for the real instance) for the same row in the same
session. Documentation section 4.3 says otherwise, but it is wrong.
Example:
fooProxy = ...getFoo() returns a Foo proxy...
bar = fooProxy.makeNewBar()
// makeNewBar() = { bar = new Bar(); bar.setFoo(this); return bar }
fooClean = bar.getFoo()
assert fooProxy == fooClean // fails
When "makeNewBar" does "setFoo" the parameter "this" is the
non-proxied Foo instance. We have effectively leaked the non-proxied instance.
CGLIBLazyInitializer:155 contains a cute hack to try to avoid this--if
"makeNewBar()" returns the non-proxied Foo instance, it switches out and returns
the Foo proxy instead. However, this only solves the trivial case where the instance
method returns the instance itself.
Basically this means equals/hashCode have to be implemented all the time because the
"hibernate ensures java identity within a session" assertion is wrong.
The best fix seems like changing the cglib proxy to not proxy to a separate instance but
to proxy to its parent class. That way when "bar.setFoo(this)" was called,
"this" would still be the proxy. And then there really would be "1 instance
per database row".
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira