-->
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.  [ 9 posts ] 
Author Message
 Post subject: Running with scissors...shared references and collections.
PostPosted: Thu Jul 01, 2004 11:23 am 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
Quote:
From the ref:
Collections obey the usual rules for value types: no shared references...


Let's say you have a heirarchy of immutable objects:
A has many B has many C

Now, you have a class that contains a reference to C:
each Z has one C

Given a Z, you'd like to print a list of B, so you do something like:
z.getC().getB().getA().getBs().iterator(); //yes, very ugly.

1.) Does this constitute a 'shared reference'?
2.) Could it cause "Z" to have a current open Session while the object
it references, "C" has stale data from a closed session?
3.) What is an alternative, correct approach?

A concrete example would be:

Product Family -> Product SubFamily -> Product;
OrderItem -> Product;

Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 01, 2004 11:47 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
A shared reference would be something like:

Code:
A a1 = Session.load(A.class, 1);
A a2 = Session.load(A.class, 2);
List bs = a1.getBs();
a2.setBs(bs);


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 01, 2004 12:39 pm 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
So this is not a shared reference?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 01, 2004 12:47 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
No.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 01, 2004 2:07 pm 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
Thanks for your help Michael.

Code:
Part part = ((ReviewPart)review.getReviewParts().iterator().next()).getPart();

Code:
Part part = (Part) session.iterate("SELECT r.part FROM ReviewPart r WHERE r.review = ?", review, Hibernate.entity(review.getClass())).next();


After the first snippet, closing the session, opening a new session and
accessing a new ReviewPart returns the old Part with the old closed session
for the Part's collections. This triggers a LazyInitializationException.

The second snippet does not, it works fine. Is there an obvious reason for this?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 02, 2004 1:38 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
This is a little unclear, so to make sure I understand you...

In the first snippet, you opened a session, used it to retreive a "review", and then closed the session. You then attempted to read across "review"'s reviewParts collection. Is that correct? Is Review.reviewPart mapped as lazy? Or is Review mapped with a proxy?Either of those would explain the exception.

Why would the second snippet cause a lazy exception? Nowhere are you doing anything that would cause lazy data to get loaded.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 02, 2004 8:40 am 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
throws Lazy:
Code:
Part part = ((ReviewPart)review.getReviewParts().iterator().next()).getPart();

works fine:
Code:
Part part = (Part) session.iterate("SELECT r.part FROM ReviewPart r WHERE r.review = ?", review, Hibernate.entity(review.getClass())).next();

Quote:
Why would the second snippet cause a lazy exception? Nowhere are you doing anything that would cause lazy data to get loaded.

The 2nd snippet is the one that works, no problem.
Quote:
In the first snippet, you opened a session, used it to retreive a "review", and then closed the session. You then attempted to read across "review"'s reviewParts collection. Is that correct? Is Review.reviewPart mapped as lazy? Or is Review mapped with a proxy?Either of those would explain the exception.

2nd case works fine. 1st case throws lazy. All the collections are lazy. Both do this:
1.) open a session. (createSession(); session.lock(review, LockMode.NONE);)
2.) do some work. (starting with snippets 1 or 2).
3.) close the session. (session.connection.commit(); session.close();)
Later, I open a new session, then access a lazy collection of Part:
Code:
reviewPart.getPart().getPrices();

When I use the first version, the prices bag is owned by the old session.
When I use the second version, the prices bag is owned by the new session.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 02, 2004 12:15 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Why would opening a new session make lazy collections loaded in other sessions suddenly aware of this new session?

A lazy collection is tied to the session that opened it. That session needs to remain open in order to access it. You can lock an object to a new session and have it cascade that locking to its collections that you want to access.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 07, 2004 9:14 am 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
steve wrote:
Why would opening a new session make lazy collections loaded in other sessions suddenly aware of this new session?

Because the session was cleared, closed and the root object which initialized the collection was lock()'d to another session. I clearly do not understand reachability as it applies to Hibernate.
steve wrote:
A lazy collection is tied to the session that opened it. That session needs to remain open in order to access it. You can lock an object to a new session and have it cascade that locking to its collections that you want to access.

That's what I thought I was doing; I even went to the extreme by manually evicting the class of the suspect collections, clear()ing the session before closing it, and trying different LockModes.
My heirarchy is like: (all collections are lazy)
Review 1-to-M ReviewPart
ReviewPart 1-to-1 Part
Part 1-to-M Prices
Part 1-to-M Sales
Prices and Sales generated the problems. The 1-to-1 is somehow not cascading the lock to the collections of Part, which makes sense, but
it's the evicting I don't understand, unless it's because:
    1. Hibernate collections contain references to sessions
    2. Objects don't spontaneously change classes in Java
    3. You can evict an object from a session, but you can't evict the
    session from a collection.
    4. Consequently, if you reassociate an object with a new session, and all the objects in the graph aren't cascadable, and some of those uncascadable objects have collections, it's possible to run into a collection that has a stale session.

That would make sense, and might imply, given:
Lifecycle Relationship 1 ->Non-Lifecycle Relationship->Lifecycle Relationship 2
Locking the parent of LR1 would have no effect on LR2 because the lock wouldn't cascade thru NLR.
If that is true, then manually locking the LR2 would negate the benefits of lazy initializing in LR1.


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