-->
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.  [ 6 posts ] 
Author Message
 Post subject: CaveatEmptor and long session
PostPosted: Mon Oct 24, 2005 7:23 pm 
Beginner
Beginner

Joined: Fri Aug 20, 2004 3:45 pm
Posts: 22
Location: Florence - ITALY
Hibernate version: 3.1rc2

I'm trying to use the HibernateFilterLong found in CaveatEmptor last release and the version from:

http://hibernate.bluemars.net/43.html?cmd=prntdoc

that it is slightly different from CaveatEmptor version. In hibernate.cfg.xml I have set hibernate.current_session_context_class to ExtendedSessionContext
class (not to thread or jta).

I get this exception (please read the filter code from above link):

Quote:
org.hibernate.HibernateException: setFlushMode is not valid without active transaction

in this line of code:

Code:
// Always disable flushing for Long Session pattern
log.debug("Disabling automatic flushing of the current Session");
sf.getCurrentSession().setFlushMode(FlushMode.NEVER);


If a comment the setFlushMode line, I get this new exception:

Quote:
javax.servlet.ServletException: Transaction not successfully started

at line:

Code:
log.debug("Trying to rollback database transaction after exception");
sf.getCurrentSession().getTransaction().rollback();


So, where I must benig the transaction?
Its not automatic with getCurrentSession() ?
Why It has been manually used sf.getCurrentSession().setFlushMode(FlushMode.NEVER) although the ExtendedSessionContext class already do it?

Thanks for suggest.

Gianni
Florence (ITALY)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 7:50 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The filter is untested alpha code.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 4:40 am 
Beginner
Beginner

Joined: Fri Aug 20, 2004 3:45 pm
Posts: 22
Location: Florence - ITALY
Ok.... but not suggest for a poor, lost developer?

Thanks,
Gianni


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 4:51 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I think the idea what the filter is supposed to do is clear. Until I have time to test it you will have to fix any problems yourself though. The AOP interceptor in CaveatEmptor _is_ tested and works. Doesn't do session-per-conversation though, only session-per-request.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 26, 2005 2:55 pm 
Beginner
Beginner

Joined: Fri Aug 20, 2004 3:45 pm
Posts: 22
Location: Florence - ITALY
I've solve my problem with LongSessionFilter, so I want to share with forum.
This in my Filter code:

Code:
public class HibernateFilterLong implements Filter {
   
   private static Log log = LogFactory.getLog(HibernateFilterLong.class);
   
   private static final String HTTPSESSIONKEY = "HibernateSession";
   private static final String LONG_CONVERSATION_FLAG = "LCF";
   
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      
      HttpSession userSession = ((HttpServletRequest) request).getSession();
      Session hibernateSession = (Session) userSession.getAttribute(HTTPSESSIONKEY);
      
      if (hibernateSession != null) {
         log.debug("Binding stored Session to thread");
         hibernateSession.beginTransaction();
         ExtendedSessionContext.bind(hibernateSession);
      }
      
      try {
//         Do the work...
         chain.doFilter(request, response);
         
         if ( request.getAttribute( LONG_CONVERSATION_FLAG ) == null) {
            
            // Session-per-request pattern
            
            // Begin a database transaction if none is active already
            HibernateUtil.getCurrentSession().beginTransaction();
            
            log.debug("Flushing Session");
            HibernateUtil.getCurrentSession().flush();
            
            log.debug("Committing the database transaction");
            HibernateUtil.getCurrentSession().getTransaction().commit();
            
            log.debug("Closing and unbinding Session from thread");
            HibernateUtil.getCurrentSession().close(); // Unbind is automatic here
            
            log.debug("Removing Session from HttpSession");
            userSession.setAttribute(HTTPSESSIONKEY, null);
            
         } else {
            // Long conversation pattern
            log.debug("Committing database transaction");
            HibernateUtil.getCurrentSession().getTransaction().commit();
            
            log.debug("Unbinding Session from thread");
            hibernateSession = ExtendedSessionContext.unbind( HibernateUtil.getSessionFactory() );
            
            log.debug("Storing Session in the HttpSession");
            userSession.setAttribute(HTTPSESSIONKEY, hibernateSession);

         }
         
      } catch (StaleObjectStateException staleEx) {
         log.error("This interceptor does not implement optimistic concurrency control!");
         log.error("Your application will not work until you add compensation actions!");
//         Rollback, close everything, possibly compensate for any permanent changes
//         during the conversation, and finally restart business conversation. Maybe
//         give the user of the application a chance to merge some of his work with
//         fresh data... what you do here depends on your applications design.
         throw staleEx;
      } catch (Throwable ex) {
//         Rollback only
         try {
            log.debug("Trying to rollback database transaction after exception");
            HibernateUtil.getCurrentSession().getTransaction().rollback();
         } catch (Throwable rbEx) {
            log.error("Could not rollback transaction after exception!", rbEx);
         } finally {
            // Cleanup
            log.debug("Closing and unbinding Session from thread");
            HibernateUtil.getCurrentSession().close(); // Unbind is automatic here
            
            log.debug("Removing Session from HttpSession");
            userSession.setAttribute(HTTPSESSIONKEY, null);
         }
         
//         Let others handle it... maybe another interceptor for exceptions?
         throw new ServletException(ex);
      }
      
   }


It's very similar to Christian code. I've also invert the condition of long conversation code, so now ONLY when the attribute LONG_CONVERSATION_FLAG in present in request, the long conversation is enabled. For normal use, the session-per-request pattern, with session-in-view, is used.

Regards.


Gianni.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 26, 2005 6:14 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Feel free to edit the Wiki page if your code is tested.


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