关于hibernate 的Session session管理方面的问题,session是线程不安全的,不同于sessionfactory,你程序里面的俩个方法申请的session实际上对应同一个实例,所以两个方法都想关掉session时会出错,只对其中一个操作就没事,解决方法可参照夏昕的hibernate开发指南,ThreadLocal解决session线程安全问题 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 main中的2个操作是放在一个session里面来做的。 加一个过滤器在一次请求完成以后去统一关闭session,而在你的数据库操作方法里都不关闭session. package cn;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 javax.servlet.http.*;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;public class CloseSessionFilter implements Filter { Log logger = LogFactory.getLog(this.getClass()); /* (non-Javadoc) * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ protected FilterConfig config; public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub this.config = arg0; } /* (non-Javadoc) * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub try{ chain.doFilter((HttpServletRequest)request, (HttpServletResponse)response); } finally{ try{ HibernateUtil.commitTransaction(); //System.out.println("commit ok"); }catch (Exception e){ HibernateUtil.rollbackTransaction(); }finally{ HibernateUtil.closeSession(); System.out.println("session close"); } } } /* (non-Javadoc) * @see javax.servlet.Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub this.config = null; }} 另外HibernateUtil 类package cn;//import net.sf.hibernate.cfg.*;//import net.sf.hibernate.*;//import javax.transaction.Transaction;import org.hibernate.*;import org.hibernate.cfg.Configuration;public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Throwable ex) { ex.printStackTrace(); System.out.println("Initial SessionFactory creation failed."); throw new ExceptionInInitializerError(ex); } } public static final ThreadLocal tLocalsess = new ThreadLocal(); public static final ThreadLocal tLocaltx = new ThreadLocal(); /* * getting the thread-safe session for using */ public static Session currentSession() { Session session = (Session) tLocalsess.get(); //open a new one, if none can be found. try { if (session == null || !session.isOpen()) { session = openSession(); tLocalsess.set(session); } } catch (HibernateException e) { //throw new HibernateException(e); e.printStackTrace(); } return session; } /* * closing the thread-safe session */ public static void closeSession() { Session session = (Session) tLocalsess.get(); tLocalsess.set(null); try { if (session != null && session.isOpen()) { session.close(); System.out.println("session close"); } } catch (HibernateException e) { //throw new InfrastructureException(e); } } /* * begin the transaction */ public static void beginTransaction() { System.out.println("begin tx"); Transaction tx = (Transaction) tLocaltx.get(); try { if (tx == null) { tx = currentSession().beginTransaction(); tLocaltx.set(tx); } } catch (HibernateException e) { //throw new InfrastructureException(e); } } /* * close the transaction */ public static void commitTransaction() { Transaction tx = (Transaction) tLocaltx.get(); try { if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) tx.commit(); tLocaltx.set(null); System.out.println("commit tx"); } catch (HibernateException e) { //throw new InfrastructureException(e); } } /* * for rollbacking */ public static void rollbackTransaction() { Transaction tx = (Transaction) tLocaltx.get(); try { tLocaltx.set(null); if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) { tx.rollback(); } } catch (HibernateException e) { //throw new InfrastructureException(e); } } private static Session openSession() throws HibernateException { return getSessionFactory().openSession(); } private static SessionFactory getSessionFactory() throws HibernateException { return sessionFactory;//SingletonSessionFactory.getInstance(); }} 你的 sessionFactory 是 hibernate 帮你生成的 sessionFactory类吧,而不是 hibernate 带的 SessionFactory,因为它用了ThreadLocal把session保存成线程局部变量,当你调用完第一个查询 session.close()第二次查询的时候 sessionFactory.getSession()发现本地线程中的session不是null(只是closed),所以也会拿出来执行查询,所以造成session.closed异常解决办法有二:1,你应该通 sessionFactory的closeSession()方法(自己看看代码是叫什么方法)或关闭session,它不仅会把session close,还会把session从TLS(在win32下就叫做Thread Local Store, 线程局部存储),让下次 getSession()时取到的是一个open的session2,上面有人介绍的那样采用OpenSessionInView的模式,在一个请求中共用一个session,这样只是session的生命期会长些好好理解MyEclipse帮你生成的那个 sessionFactory类的实现,以及了解TLS知识。 1,你应该通 sessionFactory的closeSession()方法(自己看看代码是叫什么方法)或关闭session,它不仅会把session close,还会把session从TLS(在win32下就叫做Thread Local Store, 线程局部存储),让下次 getSession()时取到的是一个open的session这个讲的有点模糊,楼上的大哥能不能再把这个方法讲清楚点呢? 需要把sessionFactory.getSession();发出给看看才好 留个记号,回头再来see see 单表肯定是不会出现session关闭的情况的这个情况要么 就在xml里面 把Lazy改成false要么就在查询的时候 fetch一下 大家看这个帖"spring+hibernate一个困扰几天的问题? " 老是报session closed的问题 汗 SessionFactory 每次 getSession不是创造一个新的session啊.....session.close()也不是析构掉这个session啊......瀑布汗.......看来我的实现也要改咯...........倒真没做并发测试...... session管理方面的问题,session是线程不安全的,不同于sessionfactory,你程序里面的俩个方法申请的session实际上对应同一个实例,所以两个方法都想关掉session时会出错,只对其中一个操作就没事,解决方法可参照夏昕的hibernate开发指南,ThreadLocal解决session线程安全问题 myeclispe自动生成的HibernateSessionFactory工具类的getSession()方法得到的session是线程共享的,如果在程序中两次调用close()方法就会出错。建议使用HibernateSessionFactory.closeSession()方法关闭session URLConnection我在客户端传了一个XML我在服务器端怎么获取这个XML参数? 求ejb2.0资料 100发给了. Java 初学者 高分求Struts2国际化程序 这个错误提示是什么意思呢? 去杭州阿里巴巴做软件工程师大概月薪是多少? 请问如果快速学习web service? Hibernate中对lazy处理的问题 为什么我的jb不行啊(EJB相关) struts2项目发布后出错 请问哪里有 dukesbank的下载?谢谢 关于服务器与部署问题,各位高手,帮帮急?
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.*;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;public class CloseSessionFilter implements Filter {
Log logger = LogFactory.getLog(this.getClass());
/* (non-Javadoc)
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
protected FilterConfig config;
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
this.config = arg0;
} /* (non-Javadoc)
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
try{
chain.doFilter((HttpServletRequest)request, (HttpServletResponse)response);
}
finally{
try{
HibernateUtil.commitTransaction();
//System.out.println("commit ok");
}catch (Exception e){
HibernateUtil.rollbackTransaction();
}finally{
HibernateUtil.closeSession();
System.out.println("session close");
}
}
} /* (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
this.config = null;
}}
package cn;
//import net.sf.hibernate.cfg.*;
//import net.sf.hibernate.*;
//import javax.transaction.Transaction;import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory; static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
ex.printStackTrace();
System.out.println("Initial SessionFactory creation failed.");
throw new ExceptionInInitializerError(ex);
}
} public static final ThreadLocal tLocalsess = new ThreadLocal(); public static final ThreadLocal tLocaltx = new ThreadLocal(); /*
* getting the thread-safe session for using
*/
public static Session currentSession() {
Session session = (Session) tLocalsess.get(); //open a new one, if none can be found.
try {
if (session == null || !session.isOpen()) {
session = openSession();
tLocalsess.set(session);
}
} catch (HibernateException e) {
//throw new HibernateException(e);
e.printStackTrace();
}
return session;
} /*
* closing the thread-safe session
*/
public static void closeSession() { Session session = (Session) tLocalsess.get();
tLocalsess.set(null);
try {
if (session != null && session.isOpen()) {
session.close();
System.out.println("session close");
} } catch (HibernateException e) {
//throw new InfrastructureException(e);
}
} /*
* begin the transaction
*/
public static void beginTransaction() {
System.out.println("begin tx");
Transaction tx = (Transaction) tLocaltx.get();
try {
if (tx == null) {
tx = currentSession().beginTransaction();
tLocaltx.set(tx);
}
} catch (HibernateException e) {
//throw new InfrastructureException(e);
}
} /*
* close the transaction
*/
public static void commitTransaction() {
Transaction tx = (Transaction) tLocaltx.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())
tx.commit();
tLocaltx.set(null);
System.out.println("commit tx");
} catch (HibernateException e) {
//throw new InfrastructureException(e);
}
} /*
* for rollbacking
*/
public static void rollbackTransaction() {
Transaction tx = (Transaction) tLocaltx.get();
try {
tLocaltx.set(null);
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
tx.rollback();
}
} catch (HibernateException e) {
//throw new InfrastructureException(e);
}
} private static Session openSession() throws HibernateException {
return getSessionFactory().openSession();
} private static SessionFactory getSessionFactory() throws HibernateException {
return sessionFactory;//SingletonSessionFactory.getInstance();
}
}
1,你应该通 sessionFactory的closeSession()方法(自己看看代码是叫什么方法)或关闭session,它不仅会把session close,还会把session从TLS(在win32下就叫做Thread Local Store, 线程局部存储),让下次 getSession()时取到的是一个open的session
2,上面有人介绍的那样采用OpenSessionInView的模式,在一个请求中共用一个session,这样只是session的生命期会长些好好理解MyEclipse帮你生成的那个 sessionFactory类的实现,以及了解TLS知识。
这个讲的有点模糊,楼上的大哥能不能再把这个方法讲清楚点呢?
这个情况要么 就在xml里面 把Lazy改成false
要么就在查询的时候 fetch一下
建议使用HibernateSessionFactory.closeSession()方法关闭session