-->
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.  [ 11 posts ] 
Author Message
 Post subject: one-to-many - overwrite children not append!
PostPosted: Tue Mar 21, 2006 8:18 am 
Newbie

Joined: Wed Oct 12, 2005 4:39 pm
Posts: 15
Location: India
Hibernate version: 3.0.5

I start off from a java object of parent (not 'connected' to database). I set a Collection of children. I call the update function. What I notice is that, the older children of the parent still exist. And new children are added.

If I start off with 2 children of a parent p, and then go onto set 2 new children, I end up with 4 children. What I am looking for really is to 'over-write' the existing children. If I give 2 new children, they should not be 'appended' but should just over-write the set!

More like a component semantics! The reason I was forced to move out from component semantics is because HQL would not work so well when the children are modelled as a component. Any reason why this is so?

And can someone suggest a solution to achieve what I am looking for with out the need to explicitly delete the older children.

Thanks much.

Regards,
Raghu


Mapping documents:

A snip from the parent (StudentEnquiry class) :

<set name="workExperience" table="studentworkexperience" cascade="all-delete-orphan" inverse="true">
<key column="EnquiryId"/>
<one-to-many class="com.tuningfork.student.businessobject.enquiry.StudentWorkExperience"/>
</set>


The child:
<class name="com.tuningfork.student.businessobject.enquiry.StudentWorkExperience">
<id name="id" column="Id">
<generator class="increment"/>
</id>
<many-to-one name="enquiry" column="EnquiryId" class="com.tuningfork.student.businessobject.enquiry.StudentEnquiry" not-null="true"/>
<property name="numberOfMonths"/>
<many-to-one column="CompanyId" name="company" class="com.tuningfork.student.businessobject.Company" cascade="none"/>
<property name="designation"/>
<property name="salary"/>
</class>



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



The object being passed here is that of the parent: StudentEnquiry
[code]
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
session.update(obj);
tx.commit();
[code]




Name and version of the database you are using: MYSql


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 21, 2006 6:54 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
<set name="workExperience" table="studentworkexperience" cascade="all-delete-orphan" inverse="true">

set inverse="false"

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 22, 2006 6:07 am 
Regular
Regular

Joined: Tue Nov 29, 2005 12:31 pm
Posts: 75
Hi,

"I set a Collection of children" - before doing that make sure you have parent.getChildren().clear().

Your mappings are fine.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 23, 2006 4:43 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
Quote:
Your mappings are fine.

I don't think so - not for what he is doing - The reason I mentioned changing the inverse="true" to "false" is due to the fact that he is coming in from a "disconnected" object. and the links need to be managed by the Parent in order for him to do what he wants...

Quote:
I start off from a java object of parent (not 'connected' to database). I set a Collection of children. I call the update function. What I notice is that, the older children of the parent still exist. And new children are added.


Normally you are right if the object (parent) is not disconnected, and loaded from within the session.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 24, 2006 6:56 am 
Regular
Regular

Joined: Tue Nov 29, 2005 12:31 pm
Posts: 75
Hi,

Quote:
I start off from a java object of parent (not 'connected' to database). I set a Collection of children. I call the update function. What I notice is that, the older children of the parent still exist. And new children are added.


IMHO: This not 'connected' object is actually a 'detached object' (hibernate name). Why ? Because of the 'older children' - this means the parent was loaded from database once.

When calling session.update the 'detached object' become a 'persistent object'. And if the parent-child relationship is well build - hibernate should take care of everything. The only thing and it's a must is to call parent.getChildren().clear(). Why ?

Quote:
By default, Hibernate does not navigate an association when searching for transient
or detached objects, so saving, deleting, or reattaching a Category won’t affect
the child category objects.


Quote:
cascade="all-delete-orphan" means the same as cascade="all" but, in addition,
Hibernate deletes any persistent entity instance that has been removed
(dereferenced) from the association (for example, from a collection).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 24, 2006 11:53 am 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
My experience when dealing with this exact situation (1-to-Many) detached objects being (re)persisted is this:

1) on the detached objects - make sure the ID's are correct.
2) make sure the inverse="false" on the <set> (from the one side)
3) issue saveOrUpdate from the One side (parent), after having made changes to the parent and or objects of the set and operations on the set, like add/delete children.

And in doing so you can manage the children and the parent - ie, your mods to parent and children including any set changes will be affective.

If you don't set up inverse="false" (ie. manage set links from Parent), then it won't work. Also I experience problems trying to "merge" these objects back into the current session, since I'd potentially get a nonUniqueObjectException.

Perhaps I was doing something incorrect, but it works now, and the data is consistent after the "saveOrUpdate()...comit()". And after researching this issue with previous posts - I've heard that others got this working with "merge" by not actually doing the "saveOrUpdate", but just "commiting" - this works to get around the NonUniqueObjectException, but it failed to actually change my "set" or update anything.

Again - this is by my experience only, and all this may have had something to do with proxy vs. non-proxy or isolation level. Not sure.. but I got it working. and that is all that matter to me at the time.

If I get some time, I'd like to write a test case on this, and post it for comment by everyone to see what their comments are...

;)

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 24, 2006 10:16 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
Raghu - what worked for you?

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 26, 2006 3:56 am 
Newbie

Joined: Wed Oct 12, 2005 4:39 pm
Posts: 15
Location: India
Thanks JT.
I tried what you suggested (setting inverse=false). I got some constraint failed exception. I did not explore further into it.

And here is why:

The real relationship I want is that of a component relationship - extreme tight coupling of the lifecycle of the children with the parent. I tried the looser coupling (one-to-many mapping) only because I feel Hibernate HQL was behaving in a buggy fashion with the component mapping.

I am making another post on this which will explain the exact HQL exception. If the HQL still does not work, then I will try this back and post back how I could finally solve the issue! :-)

Thanks for the help. I was not notified about the post on my mail. Sorry for the late response.

Regards,
Raghu


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 26, 2006 1:15 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
rags_1979 wrote:
Thanks JT.
I tried what you suggested (setting inverse=false). I got some constraint failed exception. I did not explore further into it.


this is most likely due to the FK being not-null - which is a limitation in the suggested solution.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject: 4 jt_1000
PostPosted: Mon Mar 27, 2006 3:08 am 
Regular
Regular

Joined: Tue Nov 29, 2005 12:31 pm
Posts: 75
Let's see the example. I'm very interested since the children can be persisted using only one save statement.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 27, 2006 12:49 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
I posted a test case for "merge" not working properly - on this same test case, if you were to add a collection of Children to the TestObj it would behave as I indicated above (w/ inverse="false"). The only way I can get the Object and it's (newly modified set, add-delete child-items, and modify child-item) children "saved" is by using saveOrUpdate(testobj)... and cascading operations, of course.


I am still hoping that someone can help with understanding of this complete test case posting:

http://forum.hibernate.org/viewtopic.php?t=957265&highlight=


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