SpringMVC4+Hibernate4運行報錯Could not obtain transaction-synchronized Session for current thread

Hibernate4 與 spring3 集成之後, 如果在取得session 的地方使用了getCurrentSession, 可能會報一個錯:“No Session found for current thread”, 這個錯誤的原因,網上有很多解決辦法, 但具體原因的分析,卻沒有多少, 這裏轉載一個原理分析:

SessionFactory的getCurrentSession並不能保證在沒有當前Session的情況下會自動創建一個新的,這取決於CurrentSessionContext的實現,SessionFactory將調用CurrentSessionContext的currentSession()方法來獲得Session。在Spring中,如果我們在沒有配置TransactionManager並且沒有事先調用SessionFactory.openSession()的情況直接調用getCurrentSession(),那麼程序將拋出“No Session found for current thread”異常。如果配置了TranactionManager並且通過@Transactional或者聲明的方式配置的事務邊界,那麼Spring會在開始事務之前通過AOP的方式爲當前線程創建Session,此時調用getCurrentSession()將得到正確結果。

然而,產生以上異常的原因在於Spring提供了自己的CurrentSessionContext實現,如果我們不打算使用Spring,而是自己直接從hibernate.cfg.xml創建SessionFactory,並且爲在hibernate.cfg.xml
中設置current_session_context_class爲thread,也即使用了ThreadLocalSessionContext,那麼我們在調用getCurrentSession()時,如果當前線程沒有Session存在,則會創建一個綁定到當前線程。

Hibernate在默認情況下會使用JTASessionContext,Spring提供了自己SpringSessionContext,因此我們不用配置current_session_context_class,當Hibernate與Spring集成時,將使用該SessionContext,故此時調用getCurrentSession()的效果完全依賴於SpringSessionContext的實現。

在沒有Spring的情況下使用Hibernate,如果沒有在hibernate.cfg.xml中配置current_session_context_class,有沒有JTA的話,那麼程序將拋出"No CurrentSessionContext configured!"異常。此時的解決辦法是在hibernate.cfg.xml中將current_session_context_class配置成thread。

在Spring中使用Hibernate,如果我們配置了TransactionManager,那麼我們就不應該調用SessionFactory的openSession()來獲得Sessioin,因爲這樣獲得的Session並沒有被事務管理。

至於解決的辦法,可以採用如下方式:
1.  在spring 配置文件中加入

 程序代碼


<tx:annotation-driven transaction-manager="transactionManager"/>


並且在處理業務邏輯的類上採用註解

 程序代碼


@Service
public class CustomerServiceImpl implements CustomerService {  
    @Transactional
    public void saveCustomer(Customer customer) {
        customerDaoImpl.saveCustomer(customer);
    }
    ...
}



另外在 hibernate 的配置文件中,也可以增加這樣的配置來避免這個錯誤:

 程序代碼


<property name="current_session_context_class">thread</property>



需要的可以參考這裏的代碼,有源代碼下載測試:http://www.yihaomen.com/article/java/501.htm


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章