Joshua Davis wrote:

-----Original Message-----
From: Richard Wallace [mailto:[EMAIL PROTECTED] Sent: Wednesday, August 31, 2005 2:38 PM
To: MyFaces Discussion
Subject: Re: JSF + Spring + Hibernate

I do use OpenSessionInView for lazily loading objects in the same request. The problem that I've been running into is when objects loaded from Hibernate have lazily loaded collections and are put into the session before the collection gets used. Then on a future request, Hibernate tries to lazily load the objects and can't because the session used to retrieved them has been closed.

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. 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?" 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. And setting the lazy attribute to false is a workaround, but could lead to large graphs being loaded into many users HTTP sessions. 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.

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.

Rich

Reply via email to