天天看點

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;//靜态工廠模式

  if(dictionarySelect==null)

  {

  ApplicationContext

ctx  = new

  }

就好了。看來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();

session;

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

暫時可以解決此問題。。更好的辦法還在網上找到一篇文章和大家共享:

這裡提供三個解決方案 方案一:

getHibernateTemplate().find(hql);

雖然沒有手動關閉資料庫連接配接,但spring已經幫我們關閉了。

方案二:(經測試,此方案比較有效)

設定HibernateTemplate的AllowCreate為True

在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

String hql="from Item as i";

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關閉由這個DAO的SessionFactory建立的Hibernate

Session。 

修改後的代碼如下:

session = super.getSession();

String hql

= "from Item as i";

List l =

session.createQuery(hql).list();

releaseSession(session);

困擾了幾天的問題終于解決了,項目擱淺了好幾天了,就是對spring對session的管理不清楚。