-->
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.  [ 1 post ] 
Author Message
 Post subject: composite id and saving
PostPosted: Thu Dec 02, 2004 12:33 pm 
Newbie

Joined: Thu Dec 02, 2004 12:06 pm
Posts: 2
I have a problem with saving one-to-many relationships. I have an entity called fund which contains a list of categories. A category has a composite key pointing to a fund and a category-code. The cascading between the fund and categories is set to save-update.

I create a brand new list of categories and assign them to a fund. For each category I manually create the composite key classes. If I make the fund persistent using save or update the sql code generated by hibernate seems to be updating the category table. No inserts occur in the category table. If I dont manually create the composite key class for each category, I get the following hibernate exception

org.springframework.orm.hibernate.HibernateSystemException: ids for this class must be manually assigned before calling save():

It seems to me that hibernate is expecting me to create a composite key and assign it to a category. However, when I presist the fund, hibernate assumes that the category already exists because the primary key for a category is already created

Is there a way to save the categories by saving the fund and let hibernate take care of the creation of the composite-key


Hibernate version:
hibernate 2.1.3

Mapping documents:
Fund.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" >

<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1

http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->

<class
name="com.citigroup.cai.mf.vo.Fund"
table="MF_FUND_MASTER"
>

<id
name="fundId"
type="java.lang.Long"
column="FUND_ID"
>
<generator class="sequence">
<param name="sequence">MF_FUND_SEQ</param>
</generator>
</id>

<property
name="shortName"
type="java.lang.String"
column="SHORT_NAME"
not-null="true"
length="20"
>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="longName"
type="java.lang.String"
column="LONG_NAME"
length="60"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="inceptionDate"
type="java.sql.Timestamp"
column="INCEPTION_DATE"
length="7"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="taxid"
type="java.lang.String"
column="TAXID"
length="15"
/>
<property
name="comments"
type="java.lang.String"
column="COMMENTS"
length="60"
/>
<property
name="userid"
type="java.lang.String"
column="USERID"
not-null="true"
length="10"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="timestamp"
type="java.sql.Timestamp"
column="TIMESTAMP"
not-null="true"
length="10"
>
<meta attribute="use-in-tostring">true</meta>
</property>

<!-- Associations -->

<!-- bi-directional one-to-many association to FundCta -->
<set
name="fundCtas"
lazy="true"
inverse="true"
cascade="none"
>
<key>
<column name="FUND_ID" />
</key>
<one-to-many
class="com.citigroup.cai.mf.vo.FundCta"
/>
</set>
<!-- uni-directional one-to-many association to Identifier -->
<set
name="identifiers"
lazy="true"
cascade="none"
>
<key>
<column name="FUND_ID" />
</key>
<one-to-many
class="com.citigroup.cai.mf.vo.Identifier"
/>
</set>
<!-- uni-directional one-to-many association to Category -->
<set
name="categories"
outer-join="true"
cascade="save-update"
lazy="false"
>
<key>
<column name="FUND_ID" />
</key>
<one-to-many
class="com.citigroup.cai.mf.vo.Category"
/>
</set>

</class>
</hibernate-mapping>

------------------------------------------------------
category.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" >

<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1

http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->

<class
name="com.citigroup.cai.mf.vo.Category"
table="MF_FUND_CATEGORY"
>

<composite-id name="categoryPK" class="com.citigroup.cai.mf.vo.pk.CategoryPK">
<key-property
name="fundId"
column="FUND_ID"
type="java.lang.Long"
length="22"
/>
<key-property
name="categoryId"
column="CATEGORY_ID"
type="java.lang.Long"
length="22"
/>
</composite-id>

<property
name="categoryIndicator"
type="java.lang.String"
column="CATEGORY_INDICATOR"
not-null="true"
length="1"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="userid"
type="java.lang.String"
column="USERID"
not-null="true"
length="10"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="timestamp"
type="java.sql.Timestamp"
column="TIMESTAMP"
length="7"
>
<meta attribute="use-in-tostring">true</meta>
</property>

<!-- Associations -->
<!-- derived association(s) for compound key -->
<!-- uni-directional many-to-one association to CategoryCode -->
<many-to-one
name="categoryCode"
class="com.citigroup.cai.mf.vo.CategoryCode"
update="false"
insert="false"
>
<column name="CATEGORY_ID" />
</many-to-one>


<!-- end of derived association(s) -->


</class>
</hibernate-mapping>


---------------------------------------------------------
categoryCode.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" >

<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1

http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->

<class
name="com.citigroup.cai.mf.vo.CategoryCode"
table="MF_FUND_CATEGORY_CODES"
mutable="false"
>

<id
name="categoryId"
type="java.lang.Long"
column="CATEGORY_ID"
>
<generator class="sequence">
<param name="sequence">MF_FUND_CATEGORY_SEQ</param>
</generator>
</id>

<property
name="description"
type="java.lang.String"
column="DESCRIPTION"
length="50"
>
<meta attribute="use-in-tostring">true</meta>
<meta attribute="use-in-equals">true</meta>
</property>
<property
name="userid"
type="java.lang.String"
column="USERID"
length="10"
>
<meta attribute="use-in-tostring">true</meta>
</property>
<property
name="timestamp"
type="java.sql.Timestamp"
column="TIMESTAMP"
not-null="true"
length="7"
>
<meta attribute="use-in-tostring">true</meta>
</property>

<!-- Associations -->


</class>
</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():

Fund f = new Fund();
f.setShortName("CitiDev 1");
f.setLongName("Citigroup Dev");
f.setUserid("unitTest");
f.setTimestamp(new Date());
dao.create(f);

Category c = new Category();
// when I commented out the next line I got the exception
CategoryPK pk = new CategoryPK(f.getFundId(), new Long(3));
c.setCategoryIndicator("Y");
c.setCategoryPK(pk);
c.setUserid("unitTest");
c.setTimestamp(new Date());

// This is another version of the code that I have tried and got the same exception
//Category c = new Category();
//CategoryCode code = new CategoryCode();
//code.setCategoryId(new Long(2));
//c.setCategoryCode(code);
//c.setCategoryIndicator("Y");
//c.setUserid("unitTest");
//c.setTimestamp(new Date());
//f.addCategory(c);
//dao.create(f);


f.addCategory(c);
dao.update(f);

Full stack trace of any exception that occurs:

org.springframework.orm.hibernate.HibernateSystemException: ids for this class must be manually assigned before calling save(): com.citigroup.cai.mf.vo.Category; nested exception is net.sf.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.citigroup.cai.mf.vo.Category
net.sf.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.citigroup.cai.mf.vo.Category
at net.sf.hibernate.id.Assigned.generate(Assigned.java:26)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:765)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1388)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:952)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:857)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:779)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1388)
at org.springframework.orm.hibernate.HibernateTemplate$14.doInHibernate(HibernateTemplate.java:390)
at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:228)
at org.springframework.orm.hibernate.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:387)
at com.citigroup.cai.mf.dao.implement.FundDAOImp.create(FundDAOImp.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:295)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:163)
at $Proxy0.create(Unknown Source)
at com.citigroup.cai.mf.dao.FundDAOTest.testCreateFundWithCategories(FundDAOTest.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)



Name and version of the database you are using:
Oracle 9

The generated SQL (show_sql=true):
Hibernate: select MF_FUND_SEQ.nextval from dual
Hibernate: insert into MF_FUND_MASTER (SHORT_NAME, LONG_NAME, INCEPTION_DATE, TAXID, COMMENTS, USERID, TIMESTAMP, FUND_ID) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update MF_FUND_CATEGORY set CATEGORY_INDICATOR=?, USERID=?, TIMESTAMP=? where FUND_ID=? and CATEGORY_ID=?
Hibernate: update MF_FUND_CATEGORY set FUND_ID=? where FUND_ID=? and CATEGORY_ID=?

Debug level Hibernate log excerpt:


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

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.