I am having some difficulties implementing a "Table per class" inheritance mapping, as described in "Hibernate in Action" section 3.6.2.
Basically, I have a class called "ChangeRequest", which contains a Set collection called "affectedEntities". These affectedEntities are Objects derived from a CrEntity class - the derived classes are called CrAircraft and CrSystem. The "CR_ENTITY" database table has a string column called "ENTITY_TYPE", which will contain an "A" for CrAircraft, or "S" for CrSystem.
I have simplified the classes and mapping files as much as possible, but when I try to load a list of ChangeRequest objects, I get the following Hibernate exception when Hibernate attempts to load in the CR_ENTITIES:
Hibernate ExceptionObject with id: 231312 was not of the specified subclass: com.pti.hibernate.CrEntity (Discriminator: A )
Hibernate version:
3.8.3 (?) (At least that's what MyEclipse reports, if I'm reading it right)
Mapping documents:
Relevant excerpt of ChangeRequest.hbm.xml:
<set name="affectedEntities" inverse="true" cascade="all-delete-orphan">
<key column="CHANGE_REQUEST_KEY"/>
<one-to-many class="CrEntity"/>
</set>
And full contents of CrEntity.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<!-- Created Sun Jan 30 13:55:37 PST 2005 -->
<hibernate-mapping package="com.pti.hibernate">
<class name="CrEntity" table="CR_ENTITY" discriminator-value="E">
<id name="crEntityKey" column="CR_ENTITY_KEY" type="java.lang.Integer">
<generator class="native"/>
</id>
<discriminator column="ENTITY_TYPE" type="java.lang.String"/>
<many-to-one name="critem" column="CHANGE_REQUEST_KEY" class="ChangeRequest"/>
<subclass name="CrAircraft" discriminator-value="A">
<property name="aircraftkey" column="ENTITY_KEY" type="java.lang.Integer" />
</subclass>
<subclass name="CrSystem" discriminator-value="S">
<property name="systemkey" column="ENTITY_KEY" type="java.lang.Integer" />
</subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Query query = session.createQuery("select ChangeRequest from com.pti.hibernate.ChangeRequest ChangeRequest order by ChangeRequest.crNum");
return query.list();
-------
Excerpt of ChangeRequest.java:
private Set affectedEntities = new HashSet();
--------------------
Properties of CrEntity.java:
/** The composite primary key value. */
private java.lang.Integer crEntityKey;
/** The value of the simple entityType property. */
private java.lang.String entityType;
/** The foreign key value. */
private java.lang.Integer entityKey;
/** The value of the critem property. */
private ChangeRequest critem;
(getters and setters, constructor, etc. exist)
-----------
Excerpts of CrAircraft and CrSystem:
public class CrAircraft extends CrEntity {
private Integer aircraftkey;
....
}
public class CrSystem extends CrEntity {
private Integer systemkey;
....
}
(getters and setters, constructor, etc. exist)
Name and version of the database:
Interbase (not sure what version)
The generated SQL (show_sql=true):
Hibernate: select changerequ0_.CHANGE_REQUEST_KEY as CHANGE_R1_, changerequ0_.CR_NUM as CR_NUM, changerequ0_.CR_REV_NUM as CR_REV_NUM, changerequ0_.CR_TITLE as CR_TITLE, changerequ0_.CR_STATUS as CR_STATUS, changerequ0_.CR_TYPE as CR_TYPE, changerequ0_.PRIORITY as PRIORITY, changerequ0_.MONTHLY_UPDATE as MONTHLY_8_, changerequ0_.IN_SERVICE as IN_SERVICE, changerequ0_.RETROFIT as RETROFIT, changerequ0_.PRODUCTION as PRODUCTION, changerequ0_.CUST_REQUEST_DATE as CUST_RE12_, changerequ0_.CUST_RESPOND_BY_DATE as CUST_RE13_, changerequ0_.ORIGINATOR as ORIGINATOR, changerequ0_.PROG_MANAGER as PROG_MA15_, changerequ0_.PROG_ADMIN as PROG_ADMIN, changerequ0_.AIRLINE_KEY as AIRLINE17_, changerequ0_.PROG_NUM as PROG_NUM, changerequ0_.INTERNAL as INTERNAL, changerequ0_.DESC_OF_CHANGE as DESC_OF20_, changerequ0_.REASON_FOR_CHANGE as REASON_21_, changerequ0_.IMPLEMENTATION as IMPLEME22_, changerequ0_.ON_DOCK_DATE as ON_DOCK23_, changerequ0_.THIRD_PARTY_AFFECTED as THIRD_P24_, changerequ0_.DISTRIBUTION_DATE as DISTRIB25_, changerequ0_.RECORD_INSERT_DATE as RECORD_26_, changerequ0_.RECORD_INSERT_USER as RECORD_27_ from CHANGE_REQUEST changerequ0_ order by changerequ0_.CR_NUM
Hibernate: select contact0_.CONTACT_KEY as CONTACT_1_0_, contact0_.CONTACT_TYPE as CONTACT_2_0_, contact0_.OWNER_KEY as OWNER_KEY0_, contact0_.OWNER_TYPE as OWNER_TYPE0_, contact0_.NAME as NAME0_, contact0_.DEPT as DEPT0_, contact0_.TITLE as TITLE0_, contact0_.PHONE1 as PHONE10_, contact0_.PHONE2 as PHONE20_, contact0_.PHONE3 as PHONE30_, contact0_.PHONE4 as PHONE40_, contact0_.FAX as FAX0_, contact0_.EMAIL as EMAIL0_, contact0_.REGION as REGION0_, contact0_.EMPLOYEE as EMPLOYEE0_ from CONTACT contact0_ where contact0_.CONTACT_KEY=?
Hibernate: select contact0_.CONTACT_KEY as CONTACT_1_0_, contact0_.CONTACT_TYPE as CONTACT_2_0_, contact0_.OWNER_KEY as OWNER_KEY0_, contact0_.OWNER_TYPE as OWNER_TYPE0_, contact0_.NAME as NAME0_, contact0_.DEPT as DEPT0_, contact0_.TITLE as TITLE0_, contact0_.PHONE1 as PHONE10_, contact0_.PHONE2 as PHONE20_, contact0_.PHONE3 as PHONE30_, contact0_.PHONE4 as PHONE40_, contact0_.FAX as FAX0_, contact0_.EMAIL as EMAIL0_, contact0_.REGION as REGION0_, contact0_.EMPLOYEE as EMPLOYEE0_ from CONTACT contact0_ where contact0_.CONTACT_KEY=?
Hibernate: select airline0_.AIRLINE_KEY as AIRLINE_1_0_, airline0_.IATA_CODE as IATA_CODE0_, airline0_.ICAO_CODE as ICAO_CODE0_, airline0_.NAME as NAME0_ from AIRLINE airline0_ where airline0_.AIRLINE_KEY=?
Hibernate: select contact0_.CONTACT_KEY as CONTACT_1_0_, contact0_.CONTACT_TYPE as CONTACT_2_0_, contact0_.OWNER_KEY as OWNER_KEY0_, contact0_.OWNER_TYPE as OWNER_TYPE0_, contact0_.NAME as NAME0_, contact0_.DEPT as DEPT0_, contact0_.TITLE as TITLE0_, contact0_.PHONE1 as PHONE10_, contact0_.PHONE2 as PHONE20_, contact0_.PHONE3 as PHONE30_, contact0_.PHONE4 as PHONE40_, contact0_.FAX as FAX0_, contact0_.EMAIL as EMAIL0_, contact0_.REGION as REGION0_, contact0_.EMPLOYEE as EMPLOYEE0_ from CONTACT contact0_ where contact0_.CONTACT_KEY=?
Hibernate: select affecteden0_.CHANGE_REQUEST_KEY as CHANGE_R3___, affecteden0_.CR_ENTITY_KEY as CR_ENTIT1___, affecteden0_.CR_ENTITY_KEY as CR_ENTIT1_0_, affecteden0_.ENTITY_TYPE as ENTITY_T2_0_, affecteden0_.CHANGE_REQUEST_KEY as CHANGE_R3_0_, affecteden0_.ENTITY_KEY as ENTITY_KEY0_ from CR_ENTITY affecteden0_ where affecteden0_.CHANGE_REQUEST_KEY=?
|