Hi everyone,
The situation is as follows:
I have an object "Invoice" which contains a list of Product objects mapped as follows:
Code:
<class name="Invoice" table="invoices">
<id name="id" column="id" unsaved-value="-1">
<generator class="native"/>
</id>
...
<list name="products" table="invoice_products_join" lazy="false" cascade="all-delete-orphan">
<key column="invoice_id" not-null="true"/>
<list-index column="id"/>
<many-to-many class="Product" column="product_id" unique="true"/>
</list>
</class>
<class name="Product" table="invoice_products">
<id name="id" column="id" unsaved-value="-1">
<generator class="native"/>
</id>
<property name="quantity" />
<property name="netPrice" column="net_price"/>
</class>
Note that I use a table to hold invoices (invoices), another table to hold products (invoice_products) and a join table invoice_products_join that holds invoice_id, product_id and list index id to associate products with invoices.
My requirement is to load an Invoice object along with all its properties, then duplicate this object and after changing it in UI, save the duplicated invoice and its products in a new records without altering the originals.
In my approach, I copy the properties of the invoice into an new Invoice object, along with the Product list and then set the invoice and its products' id to -1 (unsaved value). When I try to save the product, I get an exception:
org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": entities.Invoice.products
at org.hibernate.engine.Collections.prepareCollectionForUpdate(Collections.java:226)
..
...
A question then raises. Since the invoice and its products IDs are set to the default unsaved value (-1), how does Hibernate figures out that the collection already exists in db when trying to save it?
I have also tried to change the product list cascade property to "all" instead of "all-delete-orphan" and manually delete unreferenced child-product objects. Hibernate then does save the duplicated invoice and its products in new records, keeping the original invoice untouched, but the associated products of the original are deleted from "invoice_products" and "invoice_products_join" tables.
I save or update invoice objects using the following method:
Code:
Transaction tx = null;
Session session = InitSessionFactory.getInstance().openSession();
try {
if (originalInvoice == null ){
tx = session.beginTransaction();
for (int i=0;i<invoice.getProducts().size();i++) {
session.save(invoice.getProducts().get(i));
productLog.debug(invoice.getProducts().get(i));
}
session.save(newInvoice);
//session.flush();
} else {
tx = session.beginTransaction();
for (int i=0;i<invoice.getProducts().size();i++) {
session.update(invoice.getProducts().get(i));
productLog.debug(invoice.getProducts().get(i));
}
session.update(invoice);
//session.flush();
}
tx.commit();
session.close()
I have stuck with that a couple of days now so any help or suggestion would be really appreciated.
-00-
Dim