spring整合hibernate关于session的管理

spring整合hibernate关于session的管理

关键字: spring session

最近在测试oa系统的时候,发现若连接几次数据库后,tomcat就完全没反应,打开log文件,发现系统抛出java.lang.IllegalStateException: Pool not open的异常。在网上找到了问题及解决方法如下:

在使用Spring进行系统开发的时候,数据库连接一般都是配置在Spring的配置文件中,并且由Spring来管理的。在利用Spring + Hibernate进行开发时也是如此。下面是一个简单的Spring + Hibernate Dao的例子:


程序代码

Java代码
public class DaoReal extends HibernateDaoSupport implements Dao {   
  1.   public List<User> getAll() {   
  2.     return super.getHibernateTemplate().find("from User");   
  3.   }   
  4. }  
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
    return super.getHibernateTemplate().find("from User");
  }
}
 

 

  在上面的这个例子中,我们并没有关闭Session,但程序并没有任何问题,那是因为Spring已经帮我们关闭了。那么再看一个例子:


程序代码

Java代码   
  1. public class DaoReal extends HibernateDaoSupport implements Dao {   
  2.   public List<User> getAll() {   
  3.     return super.getSession().createQuery("from User").list();   
  4.   }   
  5. }  
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
    return super.getSession().createQuery("from User").list();
  }
}
 

 

  这个例子会不会有问题呢?的确,上面的例子中隐藏了一个问题,数据库连接并没有被关闭,在我们的印象中这件事似乎应该是Spring的。程序执行后,好像也没有什么问题,但是连续执行该语句n次(n<=最大连接数,如果没有指定最大连接数,那么默认为10次)后,系统处于等待状态,不会继续执行了,控制台上并没有输出任何信息。打开log文件,发现系统抛出java.lang.IllegalStateException: Pool not open的异常,无法打开连接。这说明系统连接池中所有的连接都在使用中。那么我们手动关闭Session后,应该就没有问题了吧!是这样吗?修改我们的例子,如下:


程序代码

Java代码   
  1. public class DaoReal extends HibernateDaoSupport implements Dao {   
  2.   public List<User> getAll() {   
  3.     Session s = super.getSession();   
  4.     try {   
  5.       return s.createQuery("from User").list();   
  6.     } finally {   
  7.       s.close();   
  8.     }   
  9.   }   
  10. }  
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
    Session s = super.getSession();
    try {
      return s.createQuery("from User").list();
    } finally {
      s.close();
    }
  }
}
 

 

  执行n遍后依然停止响应。问题出在哪里呢?其实Spring的Session总是与某个线程绑定的,而这个线程往往就是承载Servlet或Jsp的那个线程,也就是说,它的生命周期scope是request的。在上面的例子中,我们利用getSession强制获得了Hibernate的 Session,这个Session可能是当前事务中之前使用过的,或者可能是一个新的,并不在当前事务中,Spring只对当前事务中的Session 进行关闭。

这里有3个解决方案:
方案一:

用此种方法,虽然没有手动关闭数据库连接,但spring已经帮我们关闭了

Java代码   
  1. return super.getHibernateTemplate().find(hql);  
return super.getHibernateTemplate().find(hql);
 

 

方案二:(我用这方法解决的)

设定HibernateTemplate的AllowCreate为True,允许创建一个新的session

 

Java代码   
  1. public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {   
  2.   
  3. public List queryAll() throws Exception {   
  4.   
  5.     Session session=super.getSession(true);   
  6.   
  7.     String hql="from Item as i";   
  8.   
  9.     try{   
  10.   
  11.    List l=session.createQuery(hql).list();   
  12.   
  13.     }finally{   
  14.   
  15.     session.close();   
  16.     }   
  17. }   
  18. }   
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {

public List queryAll() throws Exception {

    Session session=super.getSession(true);

    String hql="from Item as i";

    try{

   List l=session.createQuery(hql).list();

    }finally{

    session.close();
    }
}
} 
 

方案三:

Spring API:
geSession()是org.springframework.orm.hibernate3.support.HibernateDaoSupport 中的一个方法,
它可以从当前事务或者一个新的事务获得一个hibernate session.
通常使用releaseSession(org.hibernate.Session)方法与getSession()配合。
如果没有绑定线程,releaseSession关闭由这个DAO的SessionFactory创建的Hibernate Session。 
修改后的代码如下:

Java代码   
  1. public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {   
  2.   
  3. public List queryAll() throws Exception {   
  4.   
  5.     Session session = super.getSession();   
  6.   
  7.     String hql = "from Item as i";   
  8.   
  9.     List l = session.createQuery(hql).list();   
  10.   
  11.     releaseSession(session);   
  12.   
  13. }   
  14. }   
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {

public List queryAll() throws Exception {

    Session session = super.getSession();

    String hql = "from Item as i";

    List l = session.createQuery(hql).list();

    releaseSession(session);

}
} 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值