What I am reporting here is either a bug or as designed, in either case I believe the situation can be improved.
The situation occurs when I map a heirachy of Group objects. These Group objects have subclasses FilterGroup and Mediator Group.
The mapping is as follows.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.micromuse.smconfig.core.nodegrouping">
<class discriminator-value="group" name="Group" table="NODE_GROUP">
<id column="ID" name="id" type="long">
<generator class="increment"/>
</id>
<discriminator column="CLASS" force="false" insert="true"/>
<version column="VERSION" name="version" type="long"/>
<property name="guid" type="string">
<column length="64" name="GUID"/>
</property>
<property name="name" type="string">
<column length="255" name="NAME"/>
</property>
<many-to-one class="Group" column="PARENT_ID" name="parentGroup" cascade="none" lazy="false" />
<set cascade="all-delete-orphan" inverse="true" lazy="false"
name="childGroups" order-by="NAME asc" table="GROUPS">
<key column="PARENT_ID"/>
<one-to-many class="Group"/>
</set>
<subclass discriminator-value="filter" name="FilterGroup" >
<many-to-one cascade="all" class="ExpressionRoot"
column="EXPRESSION_ID" name="expressionRoot"/>
</subclass>
<subclass discriminator-value="mediator" name="MediatorGroup" >
<many-to-one class="Mediator"
column="MEDIATOR_ID" name="mediator"/>
</subclass>
</class>
</hibernate-mapping>
Then I wrote some test code for the mapped class as followsCode:
try
{
Session session = _sessionFactory.openSession();
Transaction trans = session.beginTransaction();
FilterGroup group = new FilterGroup();
group.setName("Parent");
FilterGroup child = new FilterGroup();
child.setName("Child");
HashSet children = new HashSet();
children.add(child);
group.setChildGroups(children);
child.setParentGroup(group);
session.save(group);
session.save(child);
Long id = group.getId();
Long cid = child.getId();
trans.commit();
session.close();
group = null;
session = _sessionFactory.openSession();
trans = session.beginTransaction();
Group childtop = (Group) session.createQuery("from Group WHERE id=:id").setLong("id",cid.longValue()).list().get(0);
child = (FilterGroup)childtop;
Group grp = (Group)childtop.getParentGroup();
[color=red]group = (FilterGroup)grp; [/color]
session.delete(group);
trans.commit();
session.close();
}
catch (Exception e)
{
fail("Failed in a persistance operation " + e);
}
The above code causes a ClassCastException on the highlighted command above. I find this unusual as I was able to cast the retrieved child to FilterGroup without any problems.
I also tried retrieving the parent first then getting the child then getting the parent from the child. That worked.
It looks to me like the proxied parentGroup has been proxied from Group not FilterGroup and so we can't cast it. Isn't it possible for the parent relationship to proxy the correct subclass?