Hibernate version: 2.1.6
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="com.gfs.corp.component.salesOrg.model">
<!-- SalesOrgEntity is implemented per the Composite Pattern(GoF) and favors transparency over safety -->
<class name="SalesOrgEntity" table="SALES_ORG_ENTITY">
<meta attribute="scope-class" inherit="false">public abstract</meta>
<id name="id" column="SOE_ID" type="integer">
<generator class="native"/>
</id>
<!--
<timestamp column="LAST_UPDATE_TMSTMP"
name="lastUpdateTimestamp"
unsaved-value="null"
/>
-->
<property name="description" type="string">
<column name="DESCRIPTION" length="100" not-null="true"/>
</property>
<property name="lastUpdateUserId" type="string">
<column name="LAST_UPDATE_USER_ID" length="100" not-null="true"/>
</property>
<!-- Sales Organization Entities implement the composite pattern to favor transparency over safety. -->
<set name="children" inverse="true" cascade="all">
<key column="PARENT_ID"/>
<one-to-many class="SalesOrgEntity"/>
</set>
<many-to-one name="parent" class="SalesOrgEntity" column="PARENT_ID" not-null="false" cascade="all"/>
<!-- Abstract Base for any composite nodes -->
<joined-subclass name="SalesOrgComposite" table="SALES_ORG_COMPOSITE">
<meta attribute="scope-class" inherit="false">public abstract</meta>
<key column="SOE_ID"/>
<!-- Concrete composite nodes -->
<joined-subclass name="Division" table="DIVISION">
<key column="SOE_ID"/>
<property name="companyNumber" type="integer">
<column name="COMPANY_NBR" not-null="true"/>
</property>
<property name="name" type="string">
<column name="NAME" length="40" not-null="true"/>
</property>
<property name="acronym" type="string">
<column name="ACRONYM_TXT" length="5"/>
</property>
<property name="humanResourcesCode" type="string">
<column name="HR_DIVISION_CODE" length="10"/>
</property>
</joined-subclass>
<joined-subclass name="Segment" table="SEGMENT">
<key column="SOE_ID"/>
<property name="companyNumber" type="integer">
<column name="COMPANY_NBR"/>
</property>
<property name="managerId" type="integer">
<column name="MGR_ID"/>
</property>
<property name="segmentTypeCode" type="integer">
<column name="SEGMENT_TYPE_CODE"/>
</property>
</joined-subclass>
<joined-subclass name="BURegion" table="BU_REGION">
<key column="SOE_ID"/>
<property name="companyNumber" type="integer">
<column name="COMPANY_NBR"/>
</property>
<property name="departmentId" type="string">
<column name="DEPARTMENT_ID" length="5"/>
</property>
<property name="salesSurveyCode" type="integer">
<column name="SALES_SURVEY_CODE" length="6"/>
</property>
<property name="managerId" type="integer">
<column name="MGR_ID"/>
</property>
<property name="processLevelCode" type="string">
<column name="PROC_LVL_CODE" length="5"/>
</property>
<property name="marketingRegion" type="boolean">
<column name="MARKETING_REGION_IND" not-null="true"/>
</property>
</joined-subclass>
<joined-subclass name="Market" table="MARKET">
<key column="SOE_ID"/>
<property name="managerId" type="integer">
<column name="MGR_ID"/>
</property>
</joined-subclass>
</joined-subclass>
<!-- Leaf Node(s) -->
<joined-subclass name="Territory" table="TERRITORY">
<key column="SOE_ID"/>
<property name="employeeNumber" type="integer">
<column name="EMPLOYEE_NBR"/>
</property>
<property name="territoryTypeCode" type="integer">
<column name="TERRITORY_TYPE_CODE" not-null="true"/>
</property>
<property name="addedDate" type="timestamp">
<column name="ADDED_DATE" not-null="true"/>
</property>
<property name="effectiveDate" type="timestamp">
<column name="EFFECTIVE_DATE" not-null="true"/>
</property>
<property name="commissionDate" type="timestamp">
<column name="COMMISSION_DATE"/>
</property>
<property name="produceBonus" type="boolean">
<column name="PRODUCE_BONUS_IND" not-null="true"/>
</property>
<property name="winnersCircle" type="boolean">
<column name="WINNERS_CIRCLE_IND" not-null="true"/>
</property>
<property name="orderOriginId" type="integer">
<column name="ORDER_ORIGIN_ID" not-null="true"/>
</property>
<property name="salesContestId" type="integer">
<column name="SALES_CONTEST_ID"/>
</property>
<property name="salesPromoStatusCode" type="string">
<column name="SALES_PROMO_STATUS_CODE" length="1"/>
</property>
<property name="internalSalesNumber" type="integer">
<column name="INTERNAL_SALES_NBR"/>
</property>
<property name="floorPrice" type="boolean">
<column name="FLOOR_PRICE_IND" not-null="true"/>
</property>
</joined-subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
SessionFactory sf = null;
try {
sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
try {
pwmDivision.addChild(segmentA);
segmentA.addChild(regionOne);
regionOne.addChild(marketX);
marketX.addChild(territoryAlpha);
session.save(territoryAlpha);
session.flush();
} finally {
session.close();
}
} catch (HibernateException he) {
throw new RuntimeException(he.getMessage());
} finally {
if (sf != null) {
try {
sf.close();
} catch(HibernateException ex) {
// ignore this here
}
}
}
Full stack trace of any exception that occurs: n/a
Name and version of the database you are using: Oracle 9
The generated SQL (show_sql=true):
15:33:30,754 DEBUG SQL:226 - select hibernate_sequence.nextval from dual
15:33:31,025 DEBUG SQL:226 - select hibernate_sequence.nextval from dual
15:33:31,045 DEBUG SQL:226 - select hibernate_sequence.nextval from dual
15:33:31,055 DEBUG SQL:226 - select hibernate_sequence.nextval from dual
15:33:31,065 DEBUG SQL:226 - select hibernate_sequence.nextval from dual
15:33:39,537 DEBUG SQL:226 - insert into SALES_ORG_ENTITY (DESCRIPTION, LAST_UPDATE_USER_ID, PARENT_ID, SOE_ID) values (?, ?, ?, ?)
15:33:39,557 DEBUG SQL:226 - insert into SALES_ORG_COMPOSITE (SOE_ID) values (?)
15:33:39,557 DEBUG SQL:226 - insert into DIVISION (COMPANY_NBR, NAME, ACRONYM_TXT, HR_DIVISION_CODE, SOE_ID) values (?, ?, ?, ?, ?)
15:33:39,597 DEBUG SQL:226 - insert into SALES_ORG_ENTITY (DESCRIPTION, LAST_UPDATE_USER_ID, PARENT_ID, SOE_ID) values (?, ?, ?, ?)
15:33:39,597 DEBUG SQL:226 - insert into SALES_ORG_COMPOSITE (SOE_ID) values (?)
15:33:39,597 DEBUG SQL:226 - insert into SEGMENT (COMPANY_NBR, MGR_ID, SEGMENT_TYPE_CODE, SOE_ID) values (?, ?, ?, ?)
15:33:39,617 DEBUG SQL:226 - insert into SALES_ORG_ENTITY (DESCRIPTION, LAST_UPDATE_USER_ID, PARENT_ID, SOE_ID) values (?, ?, ?, ?)
15:33:39,617 DEBUG SQL:226 - insert into SALES_ORG_COMPOSITE (SOE_ID) values (?)
15:33:39,617 DEBUG SQL:226 - insert into BU_REGION (COMPANY_NBR, DEPARTMENT_ID, SALES_SURVEY_CODE, MGR_ID, PROC_LVL_CODE, MARKETING_REGION_IND, SOE_ID) values (?, ?, ?, ?, ?, ?, ?)
15:33:39,647 DEBUG SQL:226 - insert into SALES_ORG_ENTITY (DESCRIPTION, LAST_UPDATE_USER_ID, PARENT_ID, SOE_ID) values (?, ?, ?, ?)
15:33:39,647 DEBUG SQL:226 - insert into SALES_ORG_COMPOSITE (SOE_ID) values (?)
15:33:39,647 DEBUG SQL:226 - insert into MARKET (MGR_ID, SOE_ID) values (?, ?)
15:33:39,667 DEBUG SQL:226 - insert into SALES_ORG_ENTITY (DESCRIPTION, LAST_UPDATE_USER_ID, PARENT_ID, SOE_ID) values (?, ?, ?, ?)
15:33:39,667 DEBUG SQL:226 - insert into TERRITORY (EMPLOYEE_NBR, TERRITORY_TYPE_CODE, ADDED_DATE, EFFECTIVE_DATE, COMMISSION_DATE, PRODUCE_BONUS_IND, WINNERS_CIRCLE_IND, ORDER_ORIGIN_ID, SALES_CONTEST_ID, SALES_PROMO_STATUS_CODE, INTERNAL_SALES_NBR, FLOOR_PRICE_IND, SOE_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Problem: Before describing the problem, let me say that my mapping is the result of trying to fuse the polymorphism (table per subclass strategy), parent child relationships (i.e. chapter 16 of the ref guide), and composite pattern (
http://www.hibernate.org/86.html). Each one of these pieces of documentation provided pieces of what I needed, but I had to take some guesses as to the particular combination needed for my project.
All of the data inserts are occurring as expected. Since all entries are new, when I save the bottommost node in the hierarchy, the cascade from child to parent is triggering inserts on each. (If I saved the parent, the cascade there didn't seem to work.) However, ALL of the child rows end up with NULL for the PARENT_ID. I stepped thru in the IDE's debugger and found that all the parent child relationships in the POJO's were set correctly, but that at the time of calling save on the Session, setParent() gets called one additional time for the nodes, BUT with null values. This overwrites the parents set up previously. I'm not sure why this is, but it breaks the whole composite relationship I need to achieve.
Any insights would be appreciated. Thanks!