各位大虾:本人项目中现用了Hibernate(没用Spring),以下是一个查找的实际情况://=================Bean
public class Tblog implements java.io.Serializable { // Fields private Integer logId;
private Tbuser tbuser;//注意:tbuser联到另一个数据库表(Tbuser 类)
private Integer logOperateType;
private Date logDatetime;
private Integer logResult;
//.....setter/getter
}
//=================查询数据库
public class LogDAO{
public Tblog findById(java.lang.Integer id) {
log.debug("getting Tblog instance with id: " + id);
try {
Tblog instance = (Tblog) getSession().get(
"hibernate.beans.Tblog", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
} //注意,以上面代码中并没有关闭Session
}//=================Action
public class LogAction extends ActionSupport { //.....more property private Iterator<Tblog> iterator; public String execute() throws Exception {
iterator = new LogDAO().findById(id);
}
//......
}//=================JSP
//...more code <s:iterator value="iterator" >
<tr >
<td><s:property value="logDatetime"></s:property>&nbsp;</td>
<td><s:property value="tbuser.UserName"></s:property>&nbsp;</td> <td><s:property value="logOperateType"></s:property>&nbsp;</td>
<td><s:property value="logResult"></s:property>&nbsp;</td>
</tr>
</s:iterator>//...more code
在以上所有操作中,都没有关闭Hibernate Session,因为在Session查询到的数据,一直到JSP页面的引用才结束,
如果在JSP页面引用前关闭Session,上面描述的JSP代码中,红色那行:
<td><s:property value="tbuser.UserName"></s:property>&nbsp;</td>
将会取不到tbuser的值,因为需要Hibernate proxy重新检索tbuser.现在的问题是:像以上这样一个流程,Hibernate Session在哪里关闭最合理?或者有其它更好的解决办法???????????????请高手指教,本人在线刷等.

解决方案 »

  1.   

    页面显示以后关吧。写个filter在那里关
      

  2.   

    我们平时用JDBC时,throw Exception中一般在try中建立seesionfactory 再由sessionfactory建立session,同时开启事务,在操作数据库后,提交事务,而关闭session我一般放在finally中进行的。
      

  3.   

    2楼没搞清楚我的问题,要是在finally中关闭了,我JSP页面就取不到我想要的数据了
      

  4.   

    ?取不到?那spring里面的openSessionInView模式,你一般都是咋配的?
      

  5.   


    。没人要你用spring我是说,如果你用过spring的话,你有没有用过里面的openSessionInView模式难道那不是一个filter么现在只是你自己去写一个类似的filter,而已
      

  6.   


    我试过了,有效果,但还是不能关完.
    我的应用中,Session是基于线程的,    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();    public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            
    if (session == null || !session.isOpen()) {
    if (sessionFactory == null) {
    rebuildSessionFactory();
    }
    session = (sessionFactory != null) ? sessionFactory.openSession()
    : null;
    threadLocal.set(session);
    }
    l++;showLength();
            return session;
        }    public static void closeSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            threadLocal.set(null);        if (session != null) {
                session.close();
                l--;showLength();
            }        
        }貌似一次请求会开了不只一个线程,所以Filter只能关闭它工作所在的那个线程的Session,还有其它办法吗?我也继续检查.
      

  7.   

    已按上述方案解决,谢谢各位!
    主要是我测试时:l++;showLength();这两句没放对位置,修改后为
        public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            
    if (session == null || !session.isOpen()) {
    if (sessionFactory == null) {
    rebuildSessionFactory();
    }
    session = (sessionFactory != null) ? sessionFactory.openSession()
    : null;
    threadLocal.set(session);
    l++;showLength();
    }

            return session;
        }