-->
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.  [ 2 posts ] 
Author Message
 Post subject: Cascading Delete Orphan
PostPosted: Thu Feb 08, 2007 11:03 am 
Newbie

Joined: Thu Feb 08, 2007 9:46 am
Posts: 4
Hibernate version: 3.2

Mapping documents:
Code:
<hibernate-mapping>
    <class name="scratchpad.hibernate.A">
        <id name="id">
            <generator class="increment"/>
        </id>
        <list name="bs" cascade="all,delete-orphan">
            <key column="bId"/>
            <list-index column="idx"/>
            <one-to-many class="scratchpad.hibernate.B"/>
        </list>
    </class>
    <class name="scratchpad.hibernate.B">
        <id name="id">
            <generator class="increment"/>
        </id>
        <many-to-one name="a" column="aId" insert="false" update="false"/>
        <many-to-one name="c" column="cId" not-null="false"/>
    </class>
    <class name="scratchpad.hibernate.C">
        <id name="id">
            <generator class="increment"/>
        </id>
    </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
long id;

        SessionFactory factory = new Configuration().configure()
                .buildSessionFactory();
        try {
            Session s = factory.openSession();
            try {
                Transaction tx = s.beginTransaction();
                try {
                    C c = new C();
                    s.save(c);

                    B b = new B();
                    b.setC(c);
                    A a = new A();
                    a.getBs().add(b);
                    s.save(a);

                    tx.commit();
                    id = b.getId();
                } catch (Exception e) {
                    try {
                        tx.rollback();
                    } catch (Exception e2) {
                        // do nothing
                    }

                    throw e;
                }
            } finally {
                s.close();
            }

            s = factory.openSession();
            try {
                Transaction tx = s.beginTransaction();
                try {
                    A a = (A) s.load(A.class, id);
                    B b = a.getBs().get(0);
                    a.getBs().remove(b);
                    s.delete(b.getC());

                    tx.commit();
                } catch (Exception e) {
                    try {
                        tx.rollback();
                    } catch (Exception e2) {
                        // do nothing
                    }

                    throw e;
                }
            } finally {
                s.close();
            }
        } finally {
            factory.close();
        }


Name and version of the database you are using:
MySQL 5.0.33

The generated SQL (show_sql=true):
Hibernate: select max(id) from C
Hibernate: select max(id) from A
Hibernate: select max(id) from B
Hibernate: insert into C (id) values (?)
Hibernate: insert into A (id) values (?)
Hibernate: insert into B (cId, id) values (?, ?)
Hibernate: update B set bId=?, idx=? where id=?
Hibernate: select a0_.id as id0_0_ from A a0_ where a0_.id=?
Hibernate: select bs0_.bId as bId1_, bs0_.id as id1_, bs0_.idx as idx1_, bs0_.id as id1_0_, bs0_.aId as aId1_0_, bs0_.cId as cId1_0_ from B bs0_ where bs0_.bId=?
Hibernate: select c0_.id as id2_0_ from C c0_ where c0_.id=?
Hibernate: update B set cId=? where id=?
Hibernate: update B set bId=null, idx=null where bId=?
Hibernate: delete from C where id=?
Hibernate: delete from B where id=?

------------------------------------------------------------------------------

Hi,

When you have a collection that is mapped with a cascade of 'delete-orphan', why when removing an entity from the collection is the corresponding orphan delete scheduled at the end of the session's deletions queue? As you can see from my example above, when you have a relationship of A has a list of B's, B has a relationship with C, removing B from the A's list results in its deletion after C's deletion (despite the order of statements dictating C's deletion after B's). If I were to make B's relationship to C not-null, the above code would result in a FK constraint error as C would be removed before B.

You can force the correct removal of B before C with a manual delete of B like so:
Code:
  A a = (A) s.load(A.class, id);
  B b = a.getBs().get(0);
  C c = b.getC();
  a.getBs().remove(b);
  s.delete(b);
  s.delete(c);


I ask because cascading inserts, deletes always schedule their statements in-line with the original operation.

Can anyone shed any light?

Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 12, 2007 9:11 am 
Newbie

Joined: Thu Feb 08, 2007 9:46 am
Posts: 4
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2421


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