2011-03-22 61 views
0

最近我做了一些工作来检查在哪里给我们的应用程序中的会话相关的代码, ie .Getting current session(sessionFactory.getCurrentSession());为什么我们在应用程序中获得两次currentsession?

我看到这个代码发生在应用程序两次,一次在 HibernateSessionRequestFileter类

package com.persistence; 

import java.io.IOException; 

import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.hibernate.SessionFactory; 
import org.hibernate.StaleObjectStateException; 
public class HibernateSessionRequestFilter implements Filter { 

    private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class); 

    private SessionFactory sf; 

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

     try { 
      log.debug("Starting a database transaction"); 
      sf.getCurrentSession().beginTransaction(); 

      // Call the next filter (continue request processing) 
      chain.doFilter(request, response); 

      // Commit and cleanup 
      log.debug("Committing the database transaction"); 
      sf.getCurrentSession().getTransaction().commit(); 

     } 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 
      ex.printStackTrace(); 
      try { 
       if (sf.getCurrentSession().getTransaction().isActive()) { 
        log.debug("Trying to rollback database transaction after exception"); 
        //sf.getCurrentSession().getTransaction().rollback(); 
       } 
      } catch (Throwable rbEx) { 
       log.error("Could not rollback transaction after exception!", rbEx); 
      } 

      // Let others handle it... maybe another interceptor for exceptions? 
      throw new ServletException(ex); 
     } 
    } 

    public void init(FilterConfig filterConfig) throws ServletException { 
     log.debug("Initializing filter..."); 
     log.debug("Obtaining SessionFactory from static HibernateUtil singleton"); 
     sf = HibernateUtil.getSessionFactory(); 
    } 

    public void destroy() {} 


} 

另外一个在下面GenericHibernateDAO类一样,

protected Session getSession() { 

     if (session == null) { 
      session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     } else if (!session.isConnected()) { 
      session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     } 
     return session; 
    } 

任何人可以帮助我了解,为什么我们必须在两个地方进行激情? 当我们开始交易时,我们正在获得当前会话,就像我们坚持或从数据库获取对象一样,同样我们正在获得当前会话,为什么会这样呢?

回答

2

这看起来像OpenSessionInView模式的版本,其中Hibernate Session在接收​​到请求时打开,在呈现响应后关闭。

在过滤器中打开一个会话并开始一个事务。

然后请求被处理,并在道调用getCurrentSession()只能得到是当前打开的会话,它不创建一个新的会话。

dao完成它的工作。 然后过滤器提交事务并关闭会话。

+0

私人会话会话; – Elavarasi 2011-03-24 07:01:11

+0

是的,我同意你的观点,你的解释,但我仍然不能区分 如何告诉下面的代码只获得通用dao中的当前会话和相同的代码在过滤器类中获得新的会话? session = HibernateUtil.getSessionFactory()。getCurrentSession(); – Elavarasi 2011-03-24 07:08:12

+0

请明确你不明白的地方。 – 2011-03-24 11:53:45

相关问题