views:

2481

answers:

2

I'm using Hibernate with Spring in my application. I have been consistently using detached objects and reattaching them whenever I need to make calls to the database. I'm using hibernate template to take care of managing the connections for me.

My data structure is as follows:

classA: 
   <one-to-many name="classB" inverse="true" cascade="all,delete-orphan" lazy="true">

classB:
   <one-to-many name="classC" inverse="true" cascade="all,delete-orphan" lazy="false" fetch="subselect">

When I make the following call, with the potential that some of the items in classB or classC have changed, I get an error:

classA a = (classA)hibernateTemplate.merge(newClassA);

The error I get is:

[11/10/08 12:08:39:126 EST] 00000024 SystemOut     O 2008-11-10 12:08:38,876  -  - ca.thedominion.cfa.persistence.hibernate.ClassADAOImpl  :updateClassA Technical Exception occurred: 
org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [ca...classC#715590]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [ca...classC#715590]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:639)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.merge(HibernateTemplate.java:820)

Can someone explain to me why this is generating an error? As I understand it, merge should determine which, if any, objects in the tree changed, and update/delete/insert those, and not attempt to delete and re-insert any others. But this seems to be trying to delete all the elements of type classC and re-insert them.

+3  A: 

Apparently, you deleted one of your classC, but it remained in one of the collections. Now Hibernate is confused what to do: you deleted it, but collection has cascade="all" (including save, that is), and you're going to save the collection (including the deleted object).

You should remove the classC object from collection instead of deleting it directly, or do both (delete and remove from the collection).

Vladimir Dyuzhev
A: 

And how we can remove only object C from hibernate session. Can you show by example?

Thanks.