Hibernate Sessions In Flowscript

Note: This is only a draft, including code.

I ran into a problem with the solution Cocoon + Hibernate gives for closing sessions. It wasn't a fundamental problem, simply an inflexibility that needed to be addressed. The problem was that for flowscripts (CForms + Bean binding) I wanted to be able to 1) keep a hibernate session alive between user requests and 2) still take advantage of lazy initialization in the view using the ServletFilter solution given by the tutorial.

To achieve these goals I simply tweaked the doFilter function in the filter and created a HibernateSessionFacade:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// create an ArrayList to add disposable hibernate sessions to
ArrayList sessions = new ArrayList();
request.setAttribute( "DisposeHibernateSessions", sessions );

// Pass the request on to cocoon
chain.doFilter(request, response);

//List sessions = (List)request.getAttribute( "DisposeHibernateSessions" );

// After cocoon has finished processing, close the
// corresponding Hibernate sessions (see HibernateSessionFacade
if( sessions != null && sessions.size() > 0 )
{
Iterator it = sessions.iterator();

while( it.hasNext() ) {
Session hs = (Session)it.next();

if( hs != null && hs.isOpen() ) {

System.out.println("HibernateFilter: Closing Hibernate Session");

try{
hs.flush();
hs.connection().close();
hs.close();
}
catch( HibernateException e ){
System.out.println("HibernateFilter HibernateException: "+e.getMessage());
}
catch( SQLException e ){
System.out.println("HibernateFilter SQLException: "+e.getMessage());
}
}
}

}
}



function HibernateSessionFacade() {

}

HibernateSessionFacade.getSession = function( scheduleDisposal ) {
if( scheduleDisposal == undefined ) { scheduleDisposal = true; }

// Get new Session from PersistenceFactory
var factory = cocoon.getComponent( Packages.org.osspace.cocoon.hibernate.PersistenceFactory.ROLE );
var hs = factory.createSession();
if (hs == null) {
throw new Packages.org.apache.cocoon.ProcessingException( "Hibernate session is null" );
}

// Release PersistenceFactory
cocoon.releaseComponent(factory);

if( scheduleDisposal ) {
HibernateSessionFacade.scheduleDisposal( hs );
}

return hs;
}


HibernateSessionFacade.scheduleDisposal = function( hs ) {
// returns an ArrayList that was set by the HibernateFilter and adds the passed
// session to it. it will be removed at the end of the request
var sessions = cocoon.request.getAttribute( "DisposeHibernateSessions" );

if( sessions == null ) {
throw new Packages.org.apache.cocoon.ProcessingException("Could not schedule session for removal; the HibernateFilter did not create a list.");
}
sessions.add( hs );
}



This