-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Table per subclass polymorphism and the Composite pattern
PostPosted: Tue Nov 09, 2004 5:03 pm 
Newbie

Joined: Tue Nov 09, 2004 4:27 pm
Posts: 2
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!

_________________
PWM


Top
 Profile  
 
 Post subject: Table per subclass polymorphism and the Composite pattern
PostPosted: Tue Nov 09, 2004 6:07 pm 
Newbie

Joined: Tue Nov 09, 2004 4:27 pm
Posts: 2
This may be what happened:

I wanted the addChild/removeChild methods to be the only way end clients could manipulate the composite relationships.

However, Hibernate expected a setChildren method to go with my classes. I had implemented setChildren to call removeChild on each iterated child from the old set, and then call addChild on each one from the new set. Hibernate uses these in a way I didn't expect, so that the replacement set was the same one in memory I was removing from, which emptied/nulled it out.

Removing this seems to have me back on track.

_________________
PWM


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.