在開發中,碰到到了Could not obtain transaction-synchronized Session for current thread異常,因此特意記錄下。
一、問題的產生
在使用Hibernate時碰到了如下異常:

檢查了代碼發現是代碼中用sessionFactory.getCurrentSession()這樣獲取session,導致拋了這異常。
二、問題的解決過程
(1)先看下Hibernate相關的配置
Hibernate版本是4.3.7,這里先說明一下。Hibernate相關配置如下:

通過這個配置,並沒發現什么不妥的地方。
注意:
hibernate.current_session_context_class = thread
是在單獨使用Hibernate時才需要的配置,這里不用配置。
(2)從網上找答案
在網上找到一篇文章,很好的解釋了為什么會報這個錯。鏈接為:
http://blog.csdn.net/honghailiang888/article/details/53423941
這文章里面有一段話提醒了我。文章關鍵知識截圖如下

重點知識:
- (1)必須要將使用了sessionFactory.getCurrentSession()獲取session的代碼所在的方法加入到事務管理器中;否則獲取不到session了。
- (2)sessionFactory.getCurrentSession()是要基於事務的,才能實現session生命周期的管理。所以我們查詢方法上用個只讀事務就ok了。
了解到這個知識點后,我去看了下公司的項目代碼,發現沒有配事務切面,也沒有用注解事務。 所以我當時寫的代碼所在的方法是沒有加入到事務管理器中的;因此也就報了這個異常。
(3)解決問題
由於service方法沒有加入到事務管理器中,因此我修改了些配置文件。使用的不是聲明式事務,是用的注解事務,這樣方便點。配置如下:

在我剛剛報錯的Service方法中,加上了注解@Transactional(readOnly=true)

結果: 運行程序,一切正常
三、小結
在之前的開發中,一直沒碰到這個問題;突然在公司的一個小項目中碰到了這問題。回想之前的代碼,service層的方法當時都是用事務切面切中的,所以不會報這個錯。而現在這個項目,既沒有配事務切面,也沒用注解事務;所以才報這個錯。
在后續的開發中,記住:
使用了
sessionFactory.getCurrentSession()
獲取session時,需要事務的支持;也就是說這段代碼所在的方法要么被事務切面切中,要么方法上面用了注解事務。