This still doesnt work in Hibernate 3.0.1. Even in the case of a 1-n mapping it fails.
Code:
<class name="ServiceLevel" table="servicelevel">
<id name="id" column="servicelevel_id" type="long" unsaved-value="null">
<generator class="sequence">
<param name="sequence">servicelevel_sequence</param>
</generator>
</id>
<discriminator column="type"/>
<property name="name" column="name"/>
<subclass name="BaseServiceLevel" discriminator-value="0"/>
<subclass name="Accessorial" discriminator-value="1"/>
</class>
<class name="Engagement" table="engagement" lazy="false">
<id name="id" column="engagement_id" type="long" unsaved-value="null">
<generator class="sequence">
<param name="sequence">engagement_sequence</param>
</generator>
</id>
<property name="name" column="name"/>
<set name="baseServiceLevels" inverse="true" lazy="true" table="servicelevel" cascade="all-delete-orphan">
<key column="engagement_id"/>
<one-to-many class="BaseServiceLevel"/>
</set>
<set name="accessorials" inverse="true" lazy="true" table="servicelevel" cascade="all-delete-orphan">
<key column="engagement_id"/>
<one-to-many class="Accessorial"/>
</set>
</class>
Test code :
Code:
Engagement e = engagementDao.getEngagement(new Long(-1000));
Set baseServices = e.getBaseServiceLevels();
Set accessorials = e.getAccessorials();
for (Iterator iterator = baseServices.iterator(); iterator.hasNext();)
{
Object o = (Object) iterator.next();
System.out.println(o);
}
for (Iterator iterator = accessorials.iterator(); iterator.hasNext();)
{
Object o = (Object) iterator.next();
System.out.println(o);
}
In Hibernate 2.1.8, one set used to get initialized with all entries and the other would be empty however in Hibernate 3, an exception is raised.
Code:
org.hibernate.WrongClassException: Object with id: -1011 was not of the specified subclass: Accessorial (loaded object was of wrong class)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:824)
at org.hibernate.loader.Loader.getRow(Loader.java:780)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:295)
at org.hibernate.loader.Loader.doQuery(Loader.java:389)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:208)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1367)
at org.hibernate.loader.collection.OneToManyLoader.initialize(OneToManyLoader.java:107)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:488)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1356)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:171)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:134)
at EngagementDAOTestCase.testEngagement2(EngagementDAOTestCase.java:68)
SQL
Code:
select baseservic0_.engagement_id as engagement6___, baseservic0_.servicelevel_id as servicel1___, baseservic0_.servicelevel_id as servicel1_7_, baseservic0_.name as name16_7_, baseservic0_.engagement_id as engagement6_16_7_, engagement2_.engagement_id as engagement1_1_, engagement2_.name as name3_1_, from servicelevel baseservic0_, engagement engagement2_, where baseservic0_.engagement_id=?
select accessoria0_.engagement_id as engagement6___, accessoria0_.servicelevel_id as servicel1___, accessoria0_.servicelevel_id as servicel1_7_, accessoria0_.name as name16_7_, accessoria0_.engagement_id as engagement6_16_7_, engagement2_.engagement_id as engagement1_1_, engagement2_.name as name3_1_, from servicelevel accessoria0_, engagement engagement2_, where accessoria0_.engagement_id=?
As you can see the queries for baseservices and accessorials do not have a criteria with discriminator value.
For the 1-many case I can use the "where" criteria in the subclass mapping but as pointed out earlier, I cant use where for the many-many case.
Sanjiv