> >The scope of the Hibernate session must match the scope of 
> any lazily 
> >loaded objects or collections.  That's one of the rules of Hibernate 
> >(or any other ORM that I've used, for that matter).  Putting a proxy 
> >object in web session scope while the Hibernate session is 
> in request 
> >scope breaks that rule.  You need to either use a transfer 
> object, or 
> >cause Hibernate to initialize the proxy by either setting 
> the lazy attribute to false, or using
> >Hibernate.initialize().   You can also re-associate the 
> object with the
> >Hibernate session as was mentioned before.
> >
> >[EMAIL PROTECTED]
> >
> >
> >  
> >
> I think you may have skipped the rest of my email.  I 
> detailed the ways I'm working around that.

Yep, I read it.

>  I understand it 
> breaks the Hibernate contract, I was merely mentioning it as 
> a possible issue because everyone had simply been talking 
> about problems within a single request.  I just wanted to 
> point out that that is not the only issue with lazily loaded 
> objects and you need to be careful about putting them in the 
> HTTP session.
> 
> What do you mean by "use a transfer object?" 

Transfer Object is a design pattern frequently used with EJB:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html
.
Your managed beans could copy the Hibernate-mapped objects (I call them
Persistent Domain Objects) into simple POJOs that aren't mapped.  Leave
these in the session, stick them in a cache, store them in base64 encoded
hidden input fields, or whatever.

> That's the 
> first time I've ever heard anyone mention that.  The problem 
> with telling Hibernate to initialize the object graph is 
> that, in most cases I think, the use of Hibernate is 
> abstracted away from the webapp layer.  So your backing beans 
> don't really know they need to do that and even if they did 
> they couldn't.

The DAO should do it.  The backing beans (business session pattern) can ask
the DAO to do it in an abstract way.

>  And setting the lazy attribute to false is a 
> workaround, but could lead to large graphs being loaded into 
> many users HTTP sessions.  

This works for simple graphs only.  For complex graphs, your DAO (which is
the only thing in your system that should import Hibernate) can pick and
chose which objects to initialize.   What this is doing is essentially
turning your PDOs into Transfer Objects.

> Reassociating the object with the session has a similar 
> problem as trying to initialize the object from within the 
> webapp layer before putting it in the session.  Your webapp 
> simply does not know that you are using Hibernate.  And even 
> if it did, it has no access to the actual Hibernate session.
> I toyed around at one time with the idea of trying to create 
> a servlet filter that would automatically reassociate 
> anything in the HTTP session with the Hibernate session.  
> There are a couple of problems with that tho.  First off, 
> it's not always easy to determine what objects are Hibernate 
> persisted objects and which aren't.  Second, if the actual 
> Hibernate object is wrapped in a backing bean that is 
> actually put in the HTTP session simply scanning objects in 
> the HTTP session won't work.  Finally, what convinced me it 
> was a bad idea is that the only ways to reassociate an object 
> with a Hibernate session that I was able to find is to use 
> merge(), update(), or lock().  The first two will update the 
> database with the object you provide, and locking requires 
> the underlying data in the db hasn't changed.  So you'd lose 
> any changes that could have occured while the object was in 
> the session.

Yikes! That sounds complicated.  ;)
The only reason you would want to reassociate the objects is if you want to
update them.  If you are just using the session as a cache, then these
objects should not be mapped.   That will cause all kinds of headaches.

> So, like I said, just refetching the Hibernate objects for 
> each request is much easier and doesn't cause too much extra 
> load on the database if your using the 2nd level cache.

Bingo!  You've got it there.  To me, it makes sense to use Transfer Objects,
or at least make the integration layer (where the DAOs live) able to provide
initialized sub-graphs - mapped objects turned into Transfer Objects.
Which brings me back to JSF...  My current JSF application uses DAOs that
provide the mapped objects to the business beans.   These beans create
transfer objects that are accessed by the view.   When actions that require
db modification occur, the DAO is used to look up the object again and the
new values are set into the mapped object from the transfer object.  This is
a little bit more programming if you have a separate class for the mapped
object and the transfer object, but it's not much more work at all if you
use the initialized subgraph concept.  The benefit is that there is no need
for any fancy session reassociation or anything like that.   The
presentation layer and the persistence (integration) layer are completely
separated.


HTH

[EMAIL PROTECTED]


Reply via email to