[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2110?page=c...
]
Diego Ballve commented on HHH-2110:
-----------------------------------
I got to a similar situation as Philip and at least in my case the problem is that CGLIB
will collect ALL interfaces when loading by id + class, including interfaces only defined
for some subclasses. To illustrate, I'll use Apples and Oranges, which are both
Fruits:
public interface Fruit {
String getId();
void setId(String id);
}
public class FruitImpl implements Fruit {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
public interface Apple extends Fruit {
}
public class AppleImpl extends FruitImpl implements Apple {
}
public interface Orange extends Fruit {
}
public class OrangeImpl extends FruitImpl implements Orange {
}
The mapping for that is:
<class name="fi.dae.test.FruitImpl"
proxy="fi.dae.test.Fruit">
<id name="id" type="string">
<generator class="assigned" />
</id>
<discriminator column="TYPE" type="string"/>
<subclass discriminator-value="A"
name="fi.dae.test.AppleImpl"
proxy="fi.dae.test.Apple">
</subclass>
<subclass discriminator-value="O"
name="fi.dae.test.OrangeImpl"
proxy="fi.dae.test.Orange">
</subclass>
</class>
And the test:
// create test content
Apple apple = new AppleImpl();
apple.setId("theApple");
session.save(apple);
// flush, restart transaction, get new session
...
// check that theApple is Apple, not Orange, even if loaded as Fruit
Object apple = session.load(FruitImpl.class, "theApple");
assertTrue(apple instanceof Fruit);
assertTrue(apple instanceof Apple);
assertTrue(!(apple instanceof Orange));
Hibernate is mixing Apples and Oranges!
I don't know how feasible it is, but I believe the proxy constructing algorithm should
peek into the subclasses definitions and into the value of the discriminator field, and
based on that use only the proper interfaces for that given subclass.
Proxied object causes ClassCastException when method returns
'this' in a composite hierarchy
--------------------------------------------------------------------------------------------
Key: HHH-2110
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2110
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.0.5
Environment: Hibernate 3, any database (test case uses HSQL, issue found using
Oracle)
Reporter: Philip Nightingale
Attachments: HibernateClassCastExceptionTest.zip
If a proxied object has a method that returns 'this' and the proxy type extends
the same base class as the target object and the return type of the method is the target
class type then a ClassCastException is thrown.
The error can be tracked down to the method CGLibLazyInitializer::intercept(Object,
Method, Object[], MethodProxy).
In this method, if the object returned from the method call on the target object is the
same as the target object, then instead of returning the object itself the proxy is
returned. This is fine in most cases, but in the special case described, in which the
proxy extends a base class that is also extended by the target class, then the CCE
occurs.
In the submitted test case I have a simple composite hierarchy with an abstract base type
and two concrete subtypes. Either type can contain children, but only one can be the root
of the hierarchy (and cannot itslef be a child). There is a many-to-one relationship
defined from the sub-type that may be a child to the base class.
The submitted test case is configured to use Hypersonic DB so hsqldb.jar is required on
the classpath.
Further details and code snippets from the original code that caused the exception are
posted on the Hibernate user forum (topic "ClassCastException with CGLIB Lazy
Initialization")
--
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