-->
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: Must I retrieve 1000 children to save child number 1001?
PostPosted: Fri Sep 29, 2006 6:28 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Hello,
I'm working with EMF models persisted using Elver/Teneo and Hibernate 3.1.3.

My core problem is: Given a Parent entity with a lazily fetched one-to-many "children" association to some Child object:

    Say I map the children as a list. Say one Parent has 1000 children. If I do Parent.getChildren().add(newChild) and persist. Then Parent.getChildren() will retrieve all 1000 children FIRST, and then persist the newChild. Even if I map the children association as extra-lazy, this behavior doesnt change. I tried to be clever, created a dummy child in the 1000 children, then did "From Parent p left join fetch p.children c where c.name="dummy"". This made Parent.getChildren() get initialized as a 1 member list even though there were 1000 in DB. Added the newChild. Saved, which went fine too. However newChild ended up having a list index of 2, same as a previously existing child. Next time when I retrieved the list, there were still 1000 objects, even though there were 1001 in DB, because the newer number 2 overwrote the old number 2 in memory. Ok, so I understand, all this is happening because I said I wanted a list.

    Tried to switch from a list to a set, but I'm using EMF models with Elver/Teneo mapping the models to Hibernate. The EMF models themselves only use (E)Lists in Java, and Hibernate wasnt happy trying to persist/retrieve an ArrayList to/from a set mapping, perhaps understandably so.

    Tried to switch over to a Bag. But apparently Bags have horrendous update/delete performance due to the fact that object instances cant be uniquely correlated to DB rows.

    Tried to switch over to idbag to get over a bag's unique-identification-of-objects problem. But the idbag mapping doesnt allow
    one-to-many associations at all


Can someone please suggest to me a solution? How can I save a new child to a one-to-many association without retrieving all the current children? Also, why arent one-to-many associations allowed with an idbag?

O Gods of Hibernate, I beseech you, please respond.

Thanks,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 29, 2006 11:35 pm 
Newbie

Joined: Thu Sep 28, 2006 12:27 pm
Posts: 13
Try something like:
Code:
newChild.setParent(Parent);
sess.save(newChild);


and see if that helps.


Top
 Profile  
 
 Post subject: How will it help?
PostPosted: Mon Oct 02, 2006 3:14 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Currently in the EMF model I have the child has no API to set the parent. Even if it did, newChild.setParent(Parent) would automatically internally call Parent.getChildren().add(newChild) so that the relationship is consistent within the Java objects in memory i.e. if newChild.getParent() gets you Parent, then Parent.getChildren() should get you newChild (among others) shouldnt it?

Then we'd be back to the same problem..

Or are you suggesting that newChild.setParent(Parent) should be intentionally implemented in such a way that if you in some way discover (how?) that Parent.getChildren() has NOT been initialized, then Parent.getChildren().add(newChild) NOT be called?

Thanks,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 02, 2006 4:13 pm 
Regular
Regular

Joined: Tue Sep 26, 2006 11:37 am
Posts: 115
Location: Sacramento, CA
Sundeep,

Look at this for an interesting discussion on one-to-many mapping. You may want to play with inverse=true and let the child side manage the relationship.

http://www.hibernate.org/hib_docs/v3/re ... child.html

Let me know if this helps :)

Marius


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 03, 2006 7:42 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Thank you very much Marius,
It does help in that it pointed me to some very interesting information that I needed to know, but however, my original problem is still unsolved.

So now I understand that I can let the child manage the relationship by using a <many-to-one> from the child to the parent, and "inverse=true" at the parent. However, the code they show finally is:

Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.flush();

where the parent's addChild() method is:

public void addChild(Child c) {
c.setParent(this);
children.add(c);
}

My question now is: I assume "children" in the above addChild() method is a Set, correct? When Parent p was loaded into the session, this Set is perhaps a lazily initializable Hibernate proxy implementation of the java.util.Set interface, correct? So the moment we do children.add(c) wont Hibernate really initialize this proxy and read all the children into memory?

Is there something I am missing..

Thanks again - I'm going to say "yes" to "does it help answer your question" simply to give credit to you because although my answer is still not answered (and I hope you or anyone else continues to answer), I learned something I needed to know anyway,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 03, 2006 8:17 pm 
Regular
Regular

Joined: Tue Sep 26, 2006 11:37 am
Posts: 115
Location: Sacramento, CA
Sundeep,

Thanks for the credit.

My understanding is that with inverse=true the relationship is managed by the child. As such saving the child is sufficient for saving the row in the table which automatically saves the link in the table. So you do not need to initialize all the elements in the list.

Marius


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 12:33 am 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
I see. Just so I have understood you properly, you mean that if I do newChild.setParent(Parent), without actually doing Parent.addChild(newChild), and save newChild, it will save properly?

Also, I am befuddled by the following statements in the manual (from the link you provided earlier):

"Hibernate collections are considered to be a logical part of their owning entity; never of the contained entities. This is a crucial distinction! It has the following consequences:

When we remove / add an object from / to a collection, the version number of the collection owner is incremented"

This would mean that even if we save newChild, then the version of the Parent has to be incremented. So it looks like in any case, there will be a write to the Parent anyway, doesnt it?

Also, in general, if everytime a new child is added, the version of the parent is incremented, then what happens when there are lots of new children concurrently added? I mean if there are 2 concurrent new child adds, and both see the current Parent version as 1, they each perform a transaction in which they (a) add a row to the Child table and (b) Bump up the version number of Parent to 2. Consequently, only one transaction can properly commit, no? Because they both cant set the Parent version number to 2 in properly serialized DB transactions. If you agree, doesnt this requirement (version number increase on collection modification) force serial removal/addition to collections?

Thanks

Sundeep


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.