My database looks like this (yes, I know, but it's a legacy database):
Code:
EMP_ID|EMP_LEVEL_NAME|SLS_NBR|SLS_F_NAME|SLS_L_NAME|MGR_NBR |MGR_F_NAME|MGR_L_NAME|VP_NBR|VP_F_NAME|VP_L_NAME
1 |SLS |1 |BOB |SMITH |400 |STEVE |JONES |372 |LARRY |JOHNSON
Here's the problem: When the collections are being loaded, it fires another query to find the children. However, since a given entity has its "NBR" field populated the same as its children, it gets returned. Hibernate tries to put it in the collection, and I get a WrongClassException.
Let me give an example: For the above data, when the salespeople for the Manager bean are being loaded, it queries for rows where MGR_NBR = 400. However, Steve Jones is returned, and the exception is thrown since it is expecting a Salesperson bean but gets a Manager bean.
Some questions:
1) Why doesn't Hibernate only look for the correct classes and disregard the wrong classes? (e.g. Only return rows with EMP_LEVEL_NAME = 'SLS').
2) If it doesn't disregard incorrect classes, is there a way to change my mapping documents so that I don't get this error?
I would greatly appreciate any help.
Hibernate version: 3.0.5
Mapping documents:Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="beans">
<class name="Employee" table="EMPLOYEE">
<id name="dbID" column="EMP_ID" />
<discriminator column="LEVEL_NAME" />
<subclass name="Salesperson" discriminator-value="SLS">
<property name="salespersonID" column="SLS_NBR" />
<property name="firstName" column="SLS_FIRST_NAME" />
<property name="lastName" column="SLS_LAST_NAME" />
<many-to-one name="manager" column="MGR_NBR" lazy="false" />
</subclass>
<subclass name="Manager" discriminator-value="MGR">
<property name="managerID" column="MGR_NBR" />
<property name="firstName" column="MGR_FIRST_NAME" />
<property name="lastName" column="MGR_LAST_NAME" />
<set name="salespersons" lazy="false">
<key column="MGR_NBR" />
<one-to-many class="Salesperson" />
</set>
<many-to-one name="vicePresident" column="VP_NBR" lazy="false" />
</subclass>
<subclass name="VicePresident" discriminator-value="VP">
<property name="firstName" column="VP_FIRST_NAME" />
<property name="lastName" column="VP_LAST_NAME" />
<set name="managers" lazy="false">
<key column="VP_NBR" />
<one-to-many class="Manager" />
</set>
</subclass>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Session session = MetricsDA.currentSession(getConnection());
Criteria query = session.createCriteria(Employee.class);
List list = query.list();
return list;
Full stack trace of any exception that occurs:Code:
org.hibernate.WrongClassException: Object with id: 901 was not of the specified subclass: beans.Salesperson (loaded object was of wrong class)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:890)
at org.hibernate.loader.Loader.getRow(Loader.java:846)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:305)
at org.hibernate.loader.Loader.doQuery(Loader.java:412)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1434)
at org.hibernate.loader.collection.OneToManyLoader.initialize(OneToManyLoader.java:111)
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:1430)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:280)
at org.hibernate.engine.PersistenceContext.initializeNonLazyCollections(PersistenceContext.java:796)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:223)
at org.hibernate.loader.Loader.doList(Loader.java:1593)
at org.hibernate.loader.Loader.list(Loader.java:1577)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:111)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1322)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
at DA.test(DA.java:67)
at DA.main(DA.java:61)
Name and version of the database you are using:Oracle9i Enterprise Edition Release 9.2.0.3.0
The generated SQL (show_sql=true):Code:
select this_.EMP_ID as EMP1_0_, this_.SLS_NBR as SLS3_0_0_, this_.SLS_FIRST_NAME as SLS4_0_0_, this_.SLS_LAST_NAME as SLS5_0_0_, this_.MGR_NBR as MGR6_0_0_, this_.MGR_FIRST_NAME as MGR7_0_0_, this_.MGR_LAST_NAME as MGR8_0_0_, this_.VP_NBR as VP9_0_0_, this_.VP_FIRST_NAME as VP10_0_0_, this_.VP_LAST_NAME as VP11_0_0_, this_.EMP_LEVEL_NAME as EMP2_0_ from EMPLOYEE this_