Hi,
i've been trying to implement an object with an one-to-many relationship.
The Cashsale-Object has a bag of product-objects and I just want to save the cashsale-object and all other objects should be saved by hibernate automatically.
I read in the manual that I do need: cascade="all" for the "bag" declaration. But it doesn't work fine. Every time I get a NonUniqueObjectException and only the cashsale-object without the other objects is saved.
If I do it by hand and save every single product-object before and finally the cashsale-object than everything works fine.
Can you help me with that??
Thank you very much in advance,
Thomas
Hibernate version: 3
Code:
<!-- Mapping File -->
<class name="ws.persistence.en.cashsale.Cashsale"
table="cashsale">
<id name="id" type="long" column="barverkauf_nr"
unsaved-value="0">
<generator class="native" />
</id>
<property name="shortText" type="java.lang.String">
<column name="shortText" not-null="false" />
</property>
<property name="saleDate" type="java.util.Date">
<column name="saleDate" not-null="false" />
</property>
<property name="discount" type="double">
<column name="discount" not-null="false" />
</property>
<bag name="productList" cascade="all-delete-orphan" inverse="true" lazy="false">
<key column="cs_sale" />
<one-to-many class="ws.persistence.en.cashsale.CSProduct"/>
</bag>
</class>
<class name="ws.persistence.en.cashsale.CSProduct"
table="CashsaleProduct">
<id name="id" column="id" type="long">
<generator class="native" />
</id>
<discriminator column="categorie" type="string" />
<property name="singleSalePrice" type="double">
<column name="singleSalePrice" not-null="false" />
</property>
<property name="productName" type="java.lang.String">
<column name="productName" not-null="false" />
</property>
<subclass name="ws.persistence.en.cashsale.CSProductCat1"
discriminator-value="1">
<list name="ProductCat1" table="CSProduct_Cat1">
<key column="id" />
<index column="product_id" />
<composite-element
class="ws.persistence.en.cashsale.CSProductCat1Item">
<meta attribute="extends">
ws.persistence.en.WCat1Item
</meta>
<property name="count" type="double" />
</composite-element>
</list>
</subclass>
<subclass name="ws.persistence.en.cashsale.CSProductCat2"
discriminator-value="2">
<list name="ProductCat2" table="CSProduct_Cat2">
<key column="id" />
<index column="product_id" />
<composite-element
class="ws.persistence.en.cashsale.CSProductCat2Item">
<meta attribute="extends">
ws.persistence.en.WCat2Item
</meta>
<property name="count" type="double" />
<property name="runningMtr" type="double" />
</composite-element>
</list>
</subclass>
<subclass name="ws.persistence.en.cashsale.CSProductCat3"
discriminator-value="3">
<list name="ProductCat3" table="CSProduct_Cat3">
<key column="id" />
<index column="product_id" />
<composite-element
class="ws.persistence.en.cashsale.CSProductCat3Item">
<meta attribute="extends">
ws.persistence.en.WCat3Item
</meta>
<property name="count" type="double" />
<property name="length" type="double" />
<property name="width" type="double" />
</composite-element>
</list>
</subclass>
<subclass name="ws.persistence.en.cashsale.CSProductCat4"
discriminator-value="4">
<list name="ProductCat4" table="CSProduct_Cat4">
<key column="id" />
<index column="product_id" />
<composite-element
class="ws.persistence.en.cashsale.CSProductCat4Item">
<meta attribute="extends">
ws.persistence.en.WCat4Item
</meta>
<property name="count" type="double" />
<property name="length" type="double" />
<property name="width" type="double" />
<property name="depth" type="double" />
</composite-element>
</list>
</subclass>
</class>
The code:
Code:
Cashsale cs = new Cashsale();
/**
* Add the first product to the cashsale object
*/
CSProductCat2Item p2i = new CSProductCat2Item();
p2i.setCount(1.2);
p2i.setRunningMtr(3.23);
CSProductCat2 pc2 = new CSProductCat2();
pc2.getProductCat2().add(p2i);
cs.getProductList().add(pc2);
/**
* Add the 2nd product to the cashsale object
*/
CSProductCat1Item p1i = new CSProductCat1Item();
p1i.setCount(12.2);
CSProductCat1 pc1 = new CSProductCat1();
pc1.getProductCat1().add(p1i);
cs.getProductList().add(pc1);
cs.getProductList().add(pc2);
/**
* Now we got two products in the cashsale-object
*/
Session session = InitSessionFactory.getInstance().getCurrentSession();
Transaction tx = session.beginTransaction();
/**
* Save the whole object-structure
*/
session.save(cs);
And the exception
Code:
Hibernate: insert into cashsale (shortText, saleDate, discount, sumIncVAT, dealer, customerTitle, customerName, customerStreet, customerZip, customerCity, customerDeliverStreet, customeDeliverCitye) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [ws.persistence.en.cashsale.CSProductCat4#0]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:556)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:258)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:502)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:494)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:290)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
...
Using MySQL version 5