hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
     在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
     下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
     package com.cs_oj.filter;import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.cs_oj.data.dao.HibernateSessionFactory;public class HibernateSessionFilter implements Filter {
     private static final Log log = LogFactory.getLog(HibernateSessionFilter.class);
     public void destroy() {
         // TODO Auto-generated method stub     }     public void doFilter(ServletRequest arg0, ServletResponse arg1,
             FilterChain chain) throws IOException, ServletException {
         log.debug("HibernateSessionFilter start");
         Date date=new Date();
         DateFormat df=new SimpleDateFormat("yyyy-MM-dd '时间--'HH:mm:ss");
         System.out.println("----当前时间:"+df.format(date)+"----");
         System.out.println("----------HibernateSessionFilter start-----------");//利用HibernateSessionFactory, 得到当 前线程中的session对象..HibernateSessionFactory的代码利用了ThreadLocal模式..详见..HibernateSessionFactory
        Session session=HibernateSessionFactory.getSession(); 
         log.info("HibernateSessionFilter begin transaction");
         System.out.println("HibernateSessionFilter begin transaction");
        Transaction tx=session.beginTransaction();    //开始事务
        
         log.debug("HibernateSessionFilter begin doChain");
         HttpServletResponse response=(HttpServletResponse)arg1;
         try{
             chain.doFilter(arg0, arg1);
            
             log.debug("HibernateSessionFilter begin commit");
             //没有异常,则提交
             try{
                
                 System.out.println("HibernateSessionFilter begin commit");
                 tx.commit();
                 System.out.println("HibernateSessionFilter commit success");
                
             }
             catch(Exception e){
                
                 System.out.println("HibernateSessionFilter commit failed");
                 System.out.println("HibernateSessionFilter begin rollback() ");
                 try{
                     System.out.println("HibernateSessionFilter begin rollback() ");
                     tx.rollback();
                     System.out.println("HibernateSessionFilter rollback() success ");
                 }catch(RuntimeException ex){
                     System.out.println("HibernateSessionFilter    rollback() failed");
                 }
             }
         }catch (Exception e) {
             e.printStackTrace();
             System.out.println("chain.doFilter(arg0, arg1) exception accurs ");
             System.out.println("HibernateSessionFilter begin rollback() ");
             tx.rollback();    //出现异常,回滚
             //response.sendRedirect("error.jsp");
         }
         finally{
             log.debug("HibernateSessionFilter end doChain");
             System.out.println("HibernateSessionFilter begin close session");
            HibernateSessionFactory.closeSession();
             System.out.println("*********HibernateSessionFilter close session success*********");
             log.debug("HibernateSessionFilter begin close session");
             //System.out.println("session.isOpen()="+session.isOpen());
         }     }}在web.xml文件中对上面的过滤器进行配置.
<filter>
     <filter-name>hibernateSession</filter-name>
     <filter-class>com.cs_oj.filter.HibernateSessionFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>hibernateSession</filter-name>
    <servlet-name>action</servlet-name>
   
</filter-mapping>
<servlet>
    <servlet-name>action</servlet-name>
     <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
     <init-param>.
     <init-param>
       <param-name>config</param-name>
       <param-value>/WEB-INF/struts-config.xml</param-value>
     </init-param>
     <init-param>
       <param-name>debug</param-name>
       <param-value>3</param-value>
     </init-param>
     <init-param>
       <param-name>detail</param-name>
       <param-value>3</param-value>
     </init-param>
     <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
     <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
         则对所有以.do作为后缀名的url,都会被过滤器过滤.在被过滤器过滤的action中,和业务层的方法内,只需要调用HibernateSessionFactory 的getSession()方法,得到当前线程内的session对象.用完session后,不要关闭session,而且,每次在用session进行添加和修改操作时,也不需要启动事务.

解决方案 »

  1.   


    package com.drp.business.util;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.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;/**
     * 管理session
     * @author Administrator
     *
     */
    public class HibernateFilter implements Filter {

    private static ThreadLocal hibernateHolder = new ThreadLocal();

    private static SessionFactory factory = null; public void destroy() { }

    public static Session getSession() {
    Session session = (Session)hibernateHolder.get();
    if (session == null) {
    session = factory.openSession();
    hibernateHolder.set(session);
    }
    return session;
    } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
    FilterChain filterChain) throws IOException, ServletException {
    try {
    filterChain.doFilter(servletRequest, servletResponse);
    } finally {
    Session session = (Session)hibernateHolder.get();
    if (session != null) {
    if (session.isOpen()) {
    session.close();
    }
    hibernateHolder.remove();
    }
    }
    } public void init(FilterConfig filterConfig) throws ServletException {
    try {
    Configuration cfg = new Configuration().configure();
    factory = cfg.buildSessionFactory();
    } catch (Exception e) {
    e.printStackTrace();
    throw new ServletException(e);
    }
    }}
    另外配置web.xml