-->
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.  [ 5 posts ] 
Author Message
 Post subject: Cascade delete - hibernate nulls parent id on child first
PostPosted: Wed Oct 17, 2007 11:29 am 
Beginner
Beginner

Joined: Tue Jun 27, 2006 6:14 am
Posts: 24
Hi,

I have a parent/child relationship where I want the children to be deleted when I delete the parent. The SQL generated seems to add the extra step of nulling the parent id column on the children before deleting the children.

We have a not null constraint on the parent id column which is why we are seeing this problem - one solution is to lose the constraint...

Hibernate version:
hibernate 3.2.5, annotations 3.3.0GA

Annotations:
On parent:
Quote:
@OneToMany(cascade = {javax.persistence.CascadeType.ALL})
@Cascade({org.hibernate.annotations.CascadeType.ALL})
@JoinColumn(name = "parent_id")
private Set<Child> children = new TreeSet<Child>();

On child:
Quote:
@ManyToOne
@JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable = false)
private Parent parent;


Code between sessionFactory.openSession() and session.close():
Using Spring/JPA
Quote:
Resource resource = new FileSystemResource("xxx.xml");
BeanFactory factory = new XmlBeanFactory(resource);
EntityManager sess = ((EntityManagerFactory) factory.getBean("entityManagerFactory")).createEntityManager();
EntityTransaction txn = sess.getTransaction();
txn.begin();

Parent m = (Parent) sess.createQuery("select m from Parent m where parentId=38550").getResultList().get(0);

sess.remove(m);

txn.commit();


Full stack trace of any exception that occurs:
Quote:
15:01:56,709 WARN [JDBCExceptionReporter] SQL Error: 1407, SQLState: 72000
15:01:56,709 ERROR [JDBCExceptionReporter] ORA-01407: cannot update ("SCHEMA"."TABLE"."COLUMN") to NULL

15:01:56,709 WARN [JDBCExceptionReporter] SQL Error: 1407, SQLState: 72000
15:01:56,709 ERROR [JDBCExceptionReporter] ORA-01407: cannot update ("SCHEMA"."TABLE"."COLUMN") to NULL

15:01:56,709 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:433)


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

The generated SQL (show_sql=true):
Quote:
Hibernate: update CHILD set parent_id=null where parent_id=?


All the code does is retrieve an object and then delete it.
[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 18, 2007 1:56 pm 
Beginner
Beginner

Joined: Tue Jun 27, 2006 6:14 am
Posts: 24
Hi,

Ok - looks like this is the classic parent/child confusion on my part http://www.hibernate.org/116.html#A9

Although my pathetic excuse is that its with annotations and so I was looking in those docs first...

Anyway, it seems to be working now, with the following annotiations:

On parent:
Quote:
@OneToMany(mappedBy = "parent", cascade = {javax.persistence.CascadeType.ALL})
@Cascade({org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "parent_id")
private Set<Child> children = new TreeSet<Child>();


On child:
Quote:
@ManyToOne
@OnDelete(action = org.hibernate.annotations.OnDeleteAction.CASCADE)
@JoinColumn(name = "parent_id")
private Parent parent;


This seems to have done the trick - the parent id on the child is not being nulled and the children are deleted before the parent when the parent is deleted.

Hope this helps,
Chris

PS Probably should go in the annotation forum


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 07, 2008 12:11 pm 
Newbie

Joined: Wed Aug 23, 2006 7:59 am
Posts: 7
Thank you for posting your solution. I have got the same issue and your post solved it for me! :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 13, 2008 6:56 pm 
Newbie

Joined: Sun Jan 06, 2008 8:11 pm
Posts: 6
Hi,

I have tried using this solution, but I still have not solved the problem.
The only difference is that I am using mapping files instead of annotations.

The following are my mapping files:

Parent:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.salonsmalta.actors.User" table="ProductXWebSite.dbo.WEB_USERS" lazy="false">
       
        <id name="id" type="int" column="UserID">
            <generator class="identity"/>
        </id>
       
<many-to-one name="client" class="com.salonsmalta.business.client.Client" column="ClientID"/>
               
        <set name="basicClientPictures" table="ProductXWebSite.dbo.CLIENT_PICTURES" [b]cascade="all,delete-orphan"[/b] lazy="false">            
            <key column="UserID"/>
            <one-to-many class="com.salonsmalta.business.client.BasicClientPicture" not-found="ignore" />
        </set>              
                  
    </class>
</hibernate-mapping>


Child:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.salonsmalta.business.client.BasicClientPicture" table="ProductXWebSite.dbo.CLIENT_PICTURES" lazy="false">
       
        <id name="id" type="int" column="ClientPictureID">
            <generator class="identity"/>
        </id>     
               
      <many-to-one name="user" class="com.salonsmalta.actors.User" column="UserID"
      lazy="false" [b]cascade="delete"[/b] not-null="true"/>             
       
    </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 14, 2008 8:10 pm 
Newbie

Joined: Sun Jan 06, 2008 8:11 pm
Posts: 6
Just to let you guys know that I solve my problem by adding

insert="false" update="false"

to the many-to-one tag in the child's mapping.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.