-->
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.  [ 3 posts ] 
Author Message
 Post subject: on-delete=cascade does not work for a many-to-one-relation
PostPosted: Tue Apr 12, 2005 10:18 am 
Newbie

Joined: Tue Apr 12, 2005 9:50 am
Posts: 13
Location: Karlsruhe, Germany
Hi,

I ran into a problem that on-delete="cascade" is defined in the mapping schema for a simple parent/child-relation but when I'm deleting the parent, hibernate manually deletes the child and does not allow the database to do this. However, the generated DDL includes "on delete cascade" for the foreign-key-contraint.

I tried to counter-check with a testcase from the hibernate-sources, therefore I adapted the onetomany-testcase to match my needs.
I splitted the schema into two tables, one for parents and one for the children and defined a bidirectional one-to-many-relation.

Am I just too blind to see the error or is this a bug?
A possible workaround is to define cascade="save-update" instead of cascade="all", but what would be the the sense of on-delete="cascade" in Hibernate3 except for schema-generation? I could do this in H2 already.

Thanks anyway ...
Stephan


Hibernate version:
Both 3.0-final and 3.0-rc1

Mapping documents:
Code:
<hibernate-mapping
        package="org.hibernate.test.onetomany">

        <class name="Parent" table="parent">
                <id name="id"
                        column="parent_id">
                        <generator class="increment"/>
                </id>
                <property name="name"/>
                <set name="children"
                        cascade="all"
                        inverse="true">
                        <key column="parent_id" on-delete="cascade"/>
                        <one-to-many
                                class="Child"/>
                </set>
        </class>

        <class name="Child" table="children">
                <id name="id"
                        column="child_id">
                        <generator class="increment"/>
                </id>
                <property name="name"/>
                <many-to-one name="parent"
                        class="Parent"
                        column="parent_id"
                />
        </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

Session s = openSession();
Transaction t = s.beginTransaction();
Child c = new Child();
c.setName("Child One");
Parent p = new Parent();
p.setName("Parent");
p.getChildren().add(c);
c.setParent(p);
s.save(p);
s.flush();

s.delete(p);
s.flush();
t.commit();
s.close();



Name and version of the database you are using:
Mysql-4.1.10a

The generated SQL (show_sql=true):
Hibernate: insert into parent (name, parent_id) values (?, ?)
Hibernate: insert into children (name, parent_id, child_id) values (?, ?, ?)
Hibernate: delete from children where child_id=?
Hibernate: delete from parent where parent_id=?

Exactly here I expected Hibernate not to delete the child but to let the database do the job.


Debug level Hibernate log excerpt:
16:07:38,204 DEBUG NonstrictReadWriteCache:104 - Invalidating: org.hibernate.test.onetomany.Parent.children#1
16:07:38,205 DEBUG AbstractFlushingEventListener:294 - post flush
16:07:38,208 DEBUG DefaultDeleteEventListener:90 - deleting a persistent instance
16:07:38,210 DEBUG DefaultDeleteEventListener:125 - deleting [org.hibernate.test.onetomany.Parent#1]
16:07:38,211 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,211 DEBUG Cascades:806 - processing cascade ACTION_DELETE for: org.hibernate.test.onetomany.Parent
16:07:38,211 DEBUG Cascades:855 - cascade ACTION_DELETE for collection: org.hibernate.test.onetomany.Parent.children
16:07:38,212 DEBUG Cascades:66 - cascading to delete: org.hibernate.test.onetomany.Child
16:07:38,214 DEBUG DefaultDeleteEventListener:90 - deleting a persistent instance
16:07:38,215 DEBUG DefaultDeleteEventListener:125 - deleting [org.hibernate.test.onetomany.Child#1]
16:07:38,215 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,216 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,218 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,219 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,219 DEBUG Cascades:873 - done cascade ACTION_DELETE for collection: org.hibernate.test.onetomany.Parent.childr
en
16:07:38,220 DEBUG Cascades:831 - done processing cascade ACTION_DELETE for: org.hibernate.test.onetomany.Parent
16:07:38,220 DEBUG SessionImpl:999 - setting cache mode to: NORMAL
16:07:38,222 DEBUG SessionImpl:999 - setting cache mode to: GET
16:07:38,222 DEBUG Cascades:806 - processing cascade ACTION_DELETE for: org.hibernate.test.onetomany.Parent
16:07:38,223 DEBUG Cascades:831 - done processing cascade ACTION_DELETE for: org.hibernate.test.onetomany.Parent
16:07:38,223 DEBUG SessionImpl:999 - setting cache mode to: NORMAL
16:07:38,224 DEBUG AbstractFlushingEventListener:52 - flushing session
16:07:38,224 DEBUG AbstractFlushingEventListener:102 - processing flush-time cascades
16:07:38,224 DEBUG AbstractFlushingEventListener:150 - dirty checking collections
16:07:38,225 DEBUG AbstractFlushingEventListener:167 - Flushing entities and processing referenced collections
16:07:38,225 DEBUG AbstractFlushingEventListener:203 - Processing unreferenced collections
16:07:38,226 DEBUG Collections:38 - Collection dereferenced: [org.hibernate.test.onetomany.Parent.children#1]
16:07:38,226 DEBUG AbstractFlushingEventListener:217 - Scheduling collection removes/(re)creates/updates
16:07:38,230 DEBUG AbstractFlushingEventListener:79 - Flushed: 0 insertions, 0 updates, 2 deletions to 2 objects
16:07:38,230 DEBUG AbstractFlushingEventListener:85 - Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections
16:07:38,230 DEBUG Printer:83 - listing entities:
16:07:38,231 DEBUG Printer:90 - org.hibernate.test.onetomany.Child{Parent=org.hibernate.test.onetomany.Parent#1, name=C
hild One, id=1}
16:07:38,231 DEBUG Printer:90 - org.hibernate.test.onetomany.Parent{name=Parent, children=[org.hibernate.test.onetomany
.Child#1], id=1}
16:07:38,232 DEBUG AbstractFlushingEventListener:267 - executing flush
16:07:38,232 DEBUG NonstrictReadWriteCache:104 - Invalidating: org.hibernate.test.onetomany.Parent.children#1
16:07:38,234 DEBUG BasicEntityPersister:1997 - Deleting entity: [org.hibernate.test.onetomany.Child#1]
16:07:38,235 DEBUG AbstractBatcher:258 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
16:07:38,235 DEBUG SQL:292 - delete from children where child_id=?
Hibernate: delete from children where child_id=?
16:07:38,236 DEBUG AbstractBatcher:343 - preparing statement
16:07:38,239 DEBUG LongType:59 - binding '1' to parameter: 1
16:07:38,239 DEBUG AbstractBatcher:27 - Adding to batch
16:07:38,240 DEBUG NonstrictReadWriteCache:104 - Invalidating: org.hibernate.test.onetomany.Child#1
16:07:38,242 DEBUG BasicEntityPersister:1997 - Deleting entity: [org.hibernate.test.onetomany.Parent#1]
16:07:38,242 DEBUG AbstractBatcher:54 - Executing batch size: 1
16:07:38,243 DEBUG AbstractBatcher:266 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
16:07:38,244 DEBUG AbstractBatcher:363 - closing statement
16:07:38,244 DEBUG AbstractBatcher:258 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
16:07:38,245 DEBUG SQL:292 - delete from parent where parent_id=?
Hibernate: delete from parent where parent_id=?
...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 13, 2005 2:36 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
change
Code:
                <set name="children"
                        cascade="all"
                        inverse="true">
                        <key column="parent_id" on-delete="cascade"/>
                        <one-to-many
                                class="Child"/>
                </set>

to
Code:
                <set name="children"
                        cascade="save-update,merge,persist"
                        inverse="true">
                        <key column="parent_id" on-delete="cascade"/>
                        <one-to-many
                                class="Child"/>
                </set>

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2005 2:41 am 
Newbie

Joined: Tue Apr 12, 2005 9:50 am
Posts: 13
Location: Karlsruhe, Germany
anthony wrote:
change
Code:
cascade="all"

to
Code:
cascade="save-update,merge,persist"


Is this really a feasible solution?
I know that it will work that way (that's why I use it as workaround, but
in the original announcement of this feature (see http://www.mail-archive.com/hibernate-devel%40lists.sourceforge.net/msg03801.html)
Gavin used cascade=all.
I would prefer this solution, because I do want to cascade every action on this relation ... but Hibernate should know itself (according to on-delete=cascade) that the database will do the deletions. Or has this topic already been discussed somewhere?

bye,
Stephan


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