-->
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.  [ 5 posts ] 
Author Message
 Post subject: Possible to reattach a collection in HttpSession?
PostPosted: Thu Jul 22, 2004 10:00 am 
Newbie

Joined: Fri Jun 25, 2004 9:05 pm
Posts: 13
I am in the middle of a project that is my first use of Hibernate, where all my previous O/R use has been OJB. Hence, I am still trying to get my heard wrapped around how Hibernates Session works, and all the ramifications of it.

I am trying to a write a simple Wizard interface that allows me to manipulate data from a graph that is topped by a single object. This includes lots of associations, etc. Ideally, I would like to make use of Lazy Collections in order to a give a more fluid response time, as opposed to retreiving the parent object, and having the entire graph fill up.

My issue stems from the fact that after the first page, I store my parent object in HttpSession. I do this so I can store all of the mutations that are made, and at the end save all of the data together. And as it is becoming obvious, this doesn't work on the middle pages when I attempt to iterate through Collections that are proxied because I have no open Hibernate Session (where as OJB would just open a new Session and populate them for me).

So, what is the best practice? Can I somehow reattach a non-populated collection? And if so, it seems then my DAO's and my UI need to know about that, so I have tied it to Hibernate. Or, am I making a bad design decision my keeping the intial object in session as my change-management container? Obviously, there are other ways around this (make a second object that you copy all the data into, etc), but it just seems so clean to take the object from Hibernate, dettach it, put the changes into it, and then store the changes.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 24, 2004 3:48 pm 
Beginner
Beginner

Joined: Wed Jul 21, 2004 12:28 pm
Posts: 27
Location: New York
to retrieve a lazy collection you do have to call either

Code:
Hibernate.initialize (root.getCollection())


or

Code:
root.getCollection ().size ()


at some point while the session is open and root is associated with it (or in its first level cache - in hibernate's terminology).

Given that fact you have few chioces here I will give them to you in the order I prefer (last being the most preferred, but most dificult to achieve) them:

1. Keep a session open all the time (attach it to your HTTP session) and use disconnect and reconnect for DB connection on each request or right before and after there is a save or update request. This might be problematic in regards to stale data. This approach is a BIG NO if you have data that is accessed from two or more different places.

2. Open new session upon submission of the new request, reassociate the root object with the new session, and close the session upon request's completion. This will make sure that whenever your request is processing anything there is always a session available, to avoid lazy collections problem. You can use ThreadLocal variable to help you out with this or use request attributes along with a filter. Alternatively, make use of Spring and many of your headaches will disappear into the thin air (well given that you will take some time to read Spring docs :-))

3. Use aspects to non-intrusively open session and close it. You will have to dig deep to figure this one out yourself. It is not that I do not want to give you my solution, I just think I am not good enough at AOP to give out my solutions, not yet anyway :-)

My initial findings into this approach is that you will probably have to use AspectJ here to create classes with the capability of opening/closing a session whenever neccessary "burned in". The reason for it is that hibernate created objects can not be custom proxied. So I can not make use of Spring AOP or dynaop or any of the other dynamic AOPs, because those frameworks have to create your objects to introduce the aspects. So if hibernate creates your objects they are aspects free. Even though it is possible to make hibernate create the proxies (lazy collection, or proxy setting of a class set to true for lazy initialization of the object), it is impossible to make hibernate do it in a factory capable way, where user provides the factory to hibernate that is utilized to create the proxy. I might be wrong here, but this is where my reasearch left me so far and I was doing the reasearch for one week now.

I would definitely like to hear more discussion on the #3 somewhere, since it is a must if you are trying to create one of those rich domain models.

HTH

_________________
Thanks,
Alex


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 24, 2004 7:37 pm 
Newbie

Joined: Fri Jun 25, 2004 9:05 pm
Posts: 13
tetrione wrote:

2. Open new session upon submission of the new request, reassociate the root object with the new session, and close the session upon request's completion. This will make sure that whenever your request is processing anything there is always a session available, to avoid lazy collections problem. You can use ThreadLocal variable to help you out with this or use request attributes along with a filter. Alternatively, make use of Spring and many of your headaches will disappear into the thin air (well given that you will take some time to read Spring docs :-))

HTH


I am already using Spring, and the OpenSessionInView Filter, so this might be easier than I thought! :)

Just to make sure I understand this correctly: if on subsequent requests I re-associate (LOCK) the root object with the current Hibernate Session, then all of it's collections will be able to be instantiated via lazy-mechanisims ok?

I guess I could live with that -- only down side is that I need to know about Hibernate in the Controller part of my MVC webapp, but that is a small price to pay, and can be isolated.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 09, 2004 9:33 am 
Newbie

Joined: Sat Oct 09, 2004 9:05 am
Posts: 4
I am using Spring, and the OpenSessionInView filter too and doing what tetrione described in #2. reassociating the root object with the new session.

I need to do this, as the objects retrieved (a resultset stored in a list) are the result of an very expensive query, and do not want to go back to the database everytime the user pages thru the list (the list is displayed to the user using displaytag on a jsp page), sorts the list or exports it without changing the user input.

Reassociating the object with the new session (and also making the cascade set to "all") makes lazy loading possible, but then another problem crops up to which I have no current solution.

Since session is not thread safe, multiple threads can access the same session simultaneously (esp if there are frames or the user clicks on multiple links on the page without waiting for response back from the webserver),

In this case the spring OpenSessionInView filter assigns a unique hibernate session to the different threads. The first thread, associates the objects in the collection to its hibernate session.

The next thread tries to do the same but encounters a -" Illegal attempt to associate a collection with two open sessions"
"
Code:
ERROR com.axaim.iq.webapp.action.ActionExceptionHandler  - org.springframework.orm.hibernate.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is net.sf.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
"

This is perfectly valid - but how does one handle this. Is there some way to identify if an object is associated with any hibernate session or some way to synchronise access to session variables.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 10, 2004 4:01 pm 
Newbie

Joined: Sat Oct 09, 2004 9:05 am
Posts: 4
On digging further I found a solution to the problem described above - It is a filter to synchronise client requests within a session. A filter which does this very thing and more is described here

http://www.onjava.com/pub/a/onjava/2004 ... tml?page=1


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