ClassCastException inside proxy without explicit casting in application code
----------------------------------------------------------------------------
Key: HHH-6496
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-6496
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.6.6
Environment: Hibernate version 3.6.6
database-independent
JDK 1.6
Windows 7 and Linux
CGLib and javassist
Reporter: Joseph Calzaretta
Attachments: ProxySubclassExample.zip
Noticed that an lazily-loaded entity was getting a ClassCastException inside the proxy
method without any explicit casting in the application code. I've pared down the
issue to a minimal example and attached a FunctionalTestCase. See:
{code:title=BaseClass.java}
public abstract class BaseClass
{
public abstract SubClass toSubClass();
}
{code}
{code:title=SubClass.java}
public class SubClass extends BaseClass
{
public Subclass toSubClass() {
return this;
}
}
{code}
{code:title=ProxySubclassTest.java}
public void testProxySubclass() throws Exception {
s = this.openSession();
tx = s.beginTransaction();
LazyReferenceToBaseClass lazyReferenceToBaseClass = (LazyReferenceToBaseClass)
s.load(LazyReferenceToBaseClass.class, lazyReferenceToBaseClassId);
BaseClass baseClass = lazyReferenceToBaseClass.getBaseClass();
SubClass subClass = baseClass.toSubClass();
// Throws
// java.lang.ClassCastException: BaseClass_$$_javassist_1 cannot be cast to
SubClass
// at BaseClass_$$_javassist_1.toSubClass(BaseClass_$$_javassist_1.java)
}
{code}
This is clearly related to "the dreaded proxy problem" with its variety of
solutions/workarounds(http://community.jboss.org/wiki/ProxyVisitorPattern) but in those
cases the application code makes a mistaken assumption that it can downcast a proxy. In
this example, there is no explicit downcasting, although I suppose SubClass.toSubClass()
could be considered "implicit downcasting". Within SubClass, "this"
must refer to an instance of SubClass, and it presumably should be returnable as such.
I haven't checked what's going on in the proxy code, but I presume that it sees
that it is trying to return the item corresponding to the proxy itself, and attempts to
return that proxy. However the proxy is not an instance of SubClass and there is a
ClassCastException.
I'd suggest one of the following solutions:
- have the proxy return the unproxied (already initialized) object if it cannot cast it
appropriately
- have the proxy re-proxy the already initialized object into an instance of the
appropriate class
- have some explicit documentation as to why this cannot be expected to work and why
domain classes need to avoid this behavior.
In any case it seems poor that even improperly written entity code can cause an exception
inside the proxy-specific code.
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira