Hi Simone,

 

It looks interesting and complicated! For the moment I’ve decided to detach the object from the session by calling Hibernate.initialize() on the collections and getters on the associations. This is implemented in the object’s DAO. This can be used for objects that span a web session as well as a flow. It would be handy if Hibernate provided a Hibernate.detach() method. I know this will introduce unnecessary database fetching for associations/collections that are not needed, though it’s probably better than non-lazy loading.

 

I hope to spend sometime trying to implement your “flow” wrapper – it looks interesting. Though I’m a little uncomfortable having open sessions hanging around, though as you said it doesn’t hold onto database connections.

 

Mark H


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Simone Gianni
Sent: 06 March 2006 18:31
To: [email protected]
Subject: Re: Flow and hibernate sessions

 

Hi Mark,
we had the same problem with Hibernate. I solved it with a "flow" wrapper. This wrapper wraps the flow interpreter of your choice (tested with javaflow a lot, simple tests with _javascript_, but should not give big problems), opens a new session when the flow is first accessed (map:call function), detaches the session from the DB when the flow sends a page, then retaches the same session when the continuation is invoked (map:call continuation). It schedules a task to recollect and close sessions connected to continuations which has been marked as invalid.

This magically gives you a coherent hibernate session inside your flow, but it has some drawbacks :
- Sessions are left there, open (but disconnected from the database, so the DB collection is free) for all the time it takes for the continuation tree to be marked invalid, so potentially much more than needed, but there isn't currently a notion of "flow finished", so i don't think there can be any other way. This will increase memory usage.
- It's written for a hibernate + spring configuration, since it uses spring transaction manager to set the session as "current session" while executing the flow.
- Since the DB connection is detached, it forces a "flush never" to avoid spring/hibernate to flush the connection and thus persist object while they are, for example, being edited in a form or manipulated by the flow. This means you must manually flush the connection (or the spring hibernate template in DAOs, or whatever else) to persist your changes where needed (you can access the session inside the flow with request.getAttribute("HIBERNATE_SESSION") to do whatever you want with it). This is again needed since there is no way of knowing automatically when it is ok to flush the session and when we are just in an intermediate sendpageandwait.
- Since the DB connection is detached, this can create potential problems in database transaction for databases which does not support transactions spanning different connections (which one does?) when not using another external transaction system.

But also brings many advantages :
- You can use lazy loading everywhere, since the session will be there as long as the continuation will be there.
- No more worries about objects being persisted in the middle of a flow-form interaction (thus causing hibernate exceptions, or even worse data corruption)
- Hibernate persistence will now be "horizontal and transparent", at least in your flow (DAO, or backend services, will always need to know something about hibernate)
- No problems of merging, stale objects, duplicate objects ... that would arise with other tecniques (object detach, retach; multiple sessions etc..)

We are currently developing a lot of stuff using cocoon + hibernate + spring with this component.

You can find javadoc in the main HibernateFlowAdapter2 class, explaining how to use it, feel free to ask everything you don't understand.

Unfortunately this code will not enter in the cocoon repository cause it would include dependencies on hibernate, so i think we can use this thread to keep it up to date in case you improve it.


Hope it helps!
Simone

Mark H wrote:

What is the best way to handle hibernate sessions in flow? At the moment I’m using a servlet filter to close sessions after each request but this makes it awkward when dealing with objects that span a number of requests but are within one flow function (I’m using flowscript). I could have the session span the flowscript function but if the user never finishes the flow the session will never be closed.

 

Mark H

 

--
Simone Gianni

Reply via email to