首页 > 代码库 > spring中getSession()连接关闭的问题

spring中getSession()连接关闭的问题

做OA项目中用到了从数据库读下拉框的值。方法的类被SPRING管理就是说不能通过new()得到对象。

开始的做法是

public static DictionarySelect getFromApplicationContext() {
   ApplicationContext ctx  = new ClassPathXmlApplicationContext("/applicationContext.xml");
  dictionarySelect=(DictionarySelect) ctx.getBean("TEDictionarySelect");
  return dictionarySelect;
 }

这样每次刷新页面都从配置文件中获取一个对象,多几次后出现JVM 堆溢出。最后把这个方法改成

public static DictionarySelect dictionarySelect=null;//静态工厂模式

public static DictionarySelect getFromApplicationContext() {
  if(dictionarySelect==null)
  {
  ApplicationContext ctx  = new ClassPathXmlApplicationContext("/applicationContext.xml");
  dictionarySelect=(DictionarySelect) ctx.getBean("TEDictionarySelect");
  }
  return dictionarySelect;
 }

就好了。看来SPRING管理的类如果从XML获取对象并没有回收,而且读取的速度很慢,时间长了就会使JVM堆

溢出。采用静态工厂模式把对象发在内存里一直使用暂时可以解决此问题。。更好的办法还没想到。。

 

 

第2个问题是多运行几次数据库连接就满了程序无法继续执行下去。经测试是使用SPRING的getSession()方法获得的连接没有关闭连接。在这里讨论一下SPRING SESSION管理机制。

先看代码:

public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {
 
public List queryAll() throws Exception {
// TODO Auto-generated method stub
Session session=super.getSession(true);
String hql="from Item as i";
List l=super.getSession().createQuery(hql).list();
return l;
}
}\
其实上面的代码隐藏了一个问题,数据库连接并没有被关闭,所以一直出现以上的问题。

我的解决方法还是静态模式:

public Session session;
 public Session getcurrentSession()
 {
  if(session==null)
     session=this.getSession();
  return session;
 }

Iterator it =this.getcurrentSession().createQuery(hql).list().iterator();

暂时可以解决此问题。。更好的办法还在网上找到一篇文章和大家共享:

这里提供三个解决方案 方案一:

getHibernateTemplate().find(hql);

虽然没有手动关闭数据库连接,但spring已经帮我们关闭了。

方案二:(经测试,此方案比较有效)

设定HibernateTemplateAllowCreateTrue
spring API HibernateDaoSupport
protected net.sf.hibernate.Session getSession(boolean allowCreate)
Get a Hibernate Session, either from the current transaction or a new one.
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {
 
public List queryAll() throws Exception {
// TODO Auto-generated method stub
Session session=super.getSession(true);
String hql="from Item as i";
List l=session.createQuery(hql).list();
try{
return l;
}finally{
session.close();
}
}
}
Spring API:
geSession()
org.springframework.orm.hibernate3.support.HibernateDaoSupport 中的一个方法,

它可以从当前事务或者一个新的事务获得一个hibernate 
session.
通常使用releaseSession(org.hibernate.Session)方法与getSession()配合。

如果没有绑定线程,releaseSession关闭由这个DAOSessionFactory创建的Hibernate Session。 
修改后的代码如下:
 
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {
public List queryAll() throws Exception {
// TODO Auto-generated method stub
Session session = super.getSession();
String hql = "from Item as i";
List l = session.createQuery(hql).list();
releaseSession(session);
 
}
}
困扰了几天的问题终于解决了,项目搁浅了好几天了,就是对springsession的管理不清楚。