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=?
...