Hibernate4 No Session found 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 配置文件中加入
java

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


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

注:@Transactional能夠註解在方法上也能夠註解到類上,註解到類上全部方法都使用事物管理 session

@Service


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

@Transactional

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



另外在 hibernate 的配置文件中,也能夠增長這樣的配置來避免這個錯誤: spa

注:spring管理不須要添加這個
hibernate

 <property name="current_session_context_class">thread</property>
相關文章
相關標籤/搜索