2011-09-02 74 views
20

我正在編寫一個簡單的項目,一個用Swing編寫的業務應用程序,使用Hibernate作爲後端。我來自Spring,這讓我輕鬆地使用休眠和事務。無論如何,我設法讓Hibernate工作。昨日,一邊寫一些代碼來刪除DB豆,我得到這個:爲什麼我會得到org.hibernate.HibernateException:沒有配置CurrentSessionContext

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 

缺失的代碼很簡單:

Session sess = HibernateUtil.getSession(); 
    Transaction tx = sess.beginTransaction(); 
    try { 
     tx.begin(); 
     sess.delete(ims); 
    } catch (Exception e) { 
     tx.rollback(); 
     throw e; 
    } 
    tx.commit(); 
    sess.flush(); 

和我HibernateUtil.getSession()是:

public static Session getSession() throws HibernateException { 
     Session sess = null; 
     try { 
      sess = sessionFactory.getCurrentSession(); 
     } catch (org.hibernate.HibernateException he) { 
      sess = sessionFactory.openSession(); 
     } 
     return sess; 
    } 

附加細節:我從來沒有在我的代碼中關閉一個hibernate會話,只是在應用程序關閉時。這是錯的嗎?爲什麼我在刪除(只爲該bean,其他人工作),並且我沒有進行其他操作(插入,查詢,更新)?

我看周圍,我想修改我getSession方法只是在sessionFactory.getCurrentSessionCall(),但我得到:org.hibernate.HibernateException: No CurrentSessionContext configured!

Hibernat的conf:

<hibernate-configuration> 
    <session-factory > 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost/joptel</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">******</property> 
    <property name="hibernate.connection.pool_size">1</property> 
    <property name="show_sql">true</property> 
    <property name="hibernate.hbm2ddl.auto">update</property> 


    ..mappings.. 

    </session-factory> 
</hibernate-configuration> 
+0

你的hibernate配置文件是怎麼樣的? – Santosh

回答

54

我想求你一件事,你爲什麼試圖使用「OpenSession」方法?

public static Session getSession() throws HibernateException {   
    Session sess = null;  
    try {   
     sess = sessionFactory.getCurrentSession(); 
    } catch (org.hibernate.HibernateException he) { 
     sess = sessionFactory.openSession();  
    }    
    return sess; 
} 

你不必調用openSession(),因爲getCurrentSession()方法始終是(如果線程,如果你已經配置它是)返回當前會話。

我知道了...... 你在你的hibernate.cfg.xml文件中指定當前環境

應該是:

<property name="hibernate.current_session_context_class">thread</property> 
10

沒有CurrentSessionContext配置

閱讀參考指南Contextual Sessions。您需要爲此configure some provided or custom strategy。在hibernate.cfg.xml文件中,你會與

<property name="hibernate.current_session_context_class">...</property> 

你可能想使用「線程」的值來獲得每個線程的會話配置。在使用Spring時,它會自動將其設置爲SpringSessionContext,從而允許Spring輕鬆地將Hibernate與其事務管理框架集成。

我來自Spring,這給了我簡單的方法來使用休眠和事務。

如果您熟悉Spring,爲什麼不使用它來管理Hibernate?你必須已經知道它是如何簡單和萬無一失的。

我從來沒有在應用程序關閉時關閉我的代碼中的hibernate會話。這是錯的嗎?

是的,這是非常錯誤的。沒有關閉的每個會話都是開放的數據庫連接,所以您的應用程序目前正在流失連接。

非法企圖的集合有兩個打開的會話

這意味着正是它說關聯。你試圖對已經關聯到不同會話的東西進行一些持久化操作(save(),update(),delete())。這就是當你每次隨機開啓新會話時會發生的情況,這是自從SessionFactory.getCurrentSession()在沒有設置「當前會話上下文」時總會失敗的情況。一般來說,從來沒有只是因爲其中一個不在。你需要有明確的開場和閉幕會議策略,並且不要讓任何事情在這些「策略」之外打開一個會議。這是資源泄漏和錯誤的肯定途徑,就像你遇到的那樣。

3

當我在一個門戶網站上使用Spring遠程處理與休眠時,我遇到了同樣的問題。 僅當被調用的服務方法包含多個使用hibernate會話訪問數據庫的DAO調用時,纔會出現此類問題。

而解決方法是爲具有多個DAO調用的那些方法設置@Transaction註釋。 (意味着在這種方法下所有的DOA調用都應該在一次交易之下)。

相關問題