-->
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.  [ 7 posts ] 
Author Message
 Post subject: One-shot delete on bi-directional one-to-many associations
PostPosted: Thu Jun 01, 2006 6:35 pm 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
Hey there,

After reading through the manual, HAI and 12 pages of posts matching my search criteria on the subject, i decided to post. As the subject says, I have a bi-directional parent/child relationship, mapped as inverse=true and cascade="all-delete-orphan" on the parent side. When I delete a parent instance, hibernate correctly deletes all children attached to that instance. However, sql log shows that hibernate issues a separete delete statement for each child. This behaviour is also documented in the reference manual:

Quote:
Of course, one-shot-delete does not apply to collections mapped inverse="true" is included.


The part I'm not clear about is the "Of course" part of the statement. I fail to see how an "inverse" declaration would alter the semantics of "cascade", since it's been noted elsewhere by the hibernate team that "inverse" and "cascade" declarations have no relation whatsoever.

Theoretical question aside, is there any way to get one-shot delete working on a bi-directional association?

I'm not including and mapping or code since it's working as documented, let me know if you wish to see that anyway.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 01, 2006 7:22 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
If you're using the new HQL parser, rather than the classic, then you can issue a query to delete all the children ("delete Child where parent = :parent"). This makes it a 2-shot, rather than n+1 (because you still have to delete the parent, afterwards).

The reason for the "Of course" is because the inverse="true" attribute means that the parent-to-child association is not a lifecycle-enforcing relationship. That's the whole point of it. If you want cascade="delete" to delete children a collection (as opposted to objects in a simple association), then you use inverse="false": that's what it's for.

Are you sure that you need inverse="true" on the parent-to-child collection? If you want the childrens' lifecycle to be dependent on the parent, then inverse="true" belongs on the other side of the relationship.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 10:01 am 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
tenwit wrote:
The reason for the "Of course" is because the inverse="true" attribute means that the parent-to-child association is not a lifecycle-enforcing relationship. That's the whole point of it. If you want cascade="delete" to delete children a collection (as opposted to objects in a simple association), then you use inverse="false": that's what it's for.


Hmm well, I thought "cascade" attribute is the one that defines lifecycle relationship -- Section 10.11 (Transitive persistence) of the reference manual certainly gives that impression, and makes no mention of "inverse" in the context of lifecycle enforcement.

tenwit wrote:
Are you sure that you need inverse="true" on the parent-to-child collection? If you want the childrens' lifecycle to be dependent on the parent, then inverse="true" belongs on the other side of the relationship.


That's exactly what I'm trying to accomplish actually, having the children's lifecycle bound to the parent. The reason I had inverse="true" on the parent side is, well, child side declaration (many-to-one in that case) does not support the inverse attribute. So if there's a way to move inverse="true" declaration to the child side, I can't seem to figure that one out.

I've managed to come up with a working binding with inverse="false" on the parent side, that however still fails to perform a one-shot delete. I've also isolated the behaviour to a simple mapping involving 2 tables and 2 classes only (Parent and Child, adapted from onetomany test-case from the distribution), I can post those if you need to see the specifics.

Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 5:35 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The only cascade style that makes lifecycle implications is delete-orphan. Even cascade="delete" doesn't strictly promise to delete something, it only promises to execute the delete operation on it. The delete operation might be a no-op, if the thing to be deleted has other references pointing to it. In section 10.11, the only reference to lifecycle says pretty much that:
refdocs wrote:
If the child object's lifespan is bounded by the lifespan of the of the parent object make it a lifecycle object by specifying cascade="all,delete-orphan".

inverse="false" is the attribute that really implies a lifecycle relationship.

I don't know why you're not getting a one-shot (properly, a two-shot) delete if you've got:
  • A colleciton mapping (as opposed to a bidirectional association, perhaps a many-to-many).
  • No inverse="true" attribute (adding inverse="false" makes it self-documenting)
  • cascade="delete" or cascade="delete-orphan" (or any cascade that includes either of those).

If code from the distribution isn't showing the effects that it claims to, it may be that the mapping dates from an older distribution and is simply out of date. Can you modify the mapping to produce the required results? If you can, you should send the update to Christian (he's still maintaining the docs, I think).

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 2:56 am 
Regular
Regular

Joined: Tue May 16, 2006 3:32 am
Posts: 117
I feel that one-shot-delete does not really work for entity relationships i.e. when both the parent and children are entities. If you always access the child via the parent, map the child with a value semantic using composite element. Children mapped with a value semantic would give the desired one-shot-delete.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 26, 2006 12:46 pm 
Regular
Regular

Joined: Wed Mar 15, 2006 1:48 pm
Posts: 91
Can you share your value semantic using composite element here as a sample?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 26, 2006 7:28 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
See the ref docs, section 8.2, "Collections of dependent objects".

_________________
Code tags are your friend. Know them and use them.


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