1. 程式人生 > >getCurrentSession及openSession正確開啟方式(既管治病,還管死活)(針對hibernate4.3.2版本)

getCurrentSession及openSession正確開啟方式(既管治病,還管死活)(針對hibernate4.3.2版本)

接上篇我們看到在spring配置檔案中,配置了事務,這樣在使用getCurrentSession時,只需要在方法上加上@Transcational註解即可,需要注意的是,不管你執行什麼操作,哪怕是查詢,你依然需要事務的控制。這跟上一篇提到的只有進行DDL才需要事務是兩個概念,getCurrentSession是spring管理的物件所共享的,在執行sql時,需要事務保證資料的一致性。這句話另外一層意思是,只有在spring管理的物件中,使用getCurrentSession才能獲取到有效的且是spring控制事務的session。

如果自己new物件,即便你把sessionFactory這個物件傳入物件內部,使用getCurrentSession依然會報錯。如果你根據報錯去搜索,大致會搜尋到這麼一個結論,需要在hibernate.cfg.xml中新增一個屬性

<property name="hibernate.current_session_context_class">thread</property>
加上這個屬性之後,使用getCurrentSession確實可以獲取到session物件,但此時,該物件並沒有事務的控制,需要你自己去控制事務。接下來我們可以來看一些有意思的錯誤:
一、 不新增hibernate.current_session_context_class屬性,並且在spring管理的物件之外使用getCurrentSession,程式碼及報錯如下:無論get方法有沒有@Transcational註解,都報相同的錯誤,可見@Transcational在這裡並沒有生效
public class Test1Dao {

    private SessionFactory sessionFactory;

    //通過構造器傳入SessionFactory物件
    public Test1Dao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    public List get() {
        try {
            Session session = sessionFactory.getCurrentSession();
            Transaction transaction = session.beginTransaction();
            List list = sessionFactory.getCurrentSession().createSQLQuery("SELECT  * from test_info").addEntity(TestInfo.class).list();
            transaction.commit();
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
	at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
	at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
	at com.ucredit.test.Test1Dao.get(Test1Dao.java:24)
	at com.ucredit.test.TestController.get(TestController.java:23)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
 二、加上hibernate.current_session_context_class屬性,但是去掉Test1Dao中的事務,會發現,getCurrentSession需要事務的支援
public class Test1Dao {

    private SessionFactory sessionFactory;

    //通過構造器傳入SessionFactory物件
    public Test1Dao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    public List get() {
        try {
            Session session = sessionFactory.getCurrentSession();
//            Transaction transaction = session.beginTransaction();
            List list = sessionFactory.getCurrentSession().createSQLQuery("SELECT  * from test_info").addEntity(TestInfo.class).list();
//            transaction.commit();
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
org.hibernate.HibernateException: createSQLQuery is not valid without active transaction
	at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
	at com.sun.proxy.$Proxy88.createSQLQuery(Unknown Source)
	at com.ucredit.test.Test1Dao.get(Test1Dao.java:26)
	at com.ucredit.test.TestController.get(TestController.java:23)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
 三、更新操作不生效,這個問題是針對openSession,這種方式獲取的session並不會自動提交,需要執行flush方法才能夠更新資料。
public class Test1Dao {

    private SessionFactory sessionFactory;

    //通過構造器傳入SessionFactory物件
    public Test1Dao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void update() {
        Session session = sessionFactory.openSession();
        TestInfo testInfo = (TestInfo) session.createSQLQuery("SELECT  * from test_info").addEntity(TestInfo.class).uniqueResult();
        testInfo.setName("測試");
        session.update(testInfo);
    }
}
我在hibernate配置檔案中設定了列印sql,但在控制檯只看到了select語句,沒有看到update,資料庫也沒有更新,但加上session.flush()後,執行結果如下:
Hibernate: SELECT  * from test_info
Hibernate: update test_info set key_id=?, name=? where id=?


相關推薦

getCurrentSessionopenSession正確開啟方式治病死活針對hibernate4.3.2版本

接上篇我們看到在spring配置檔案中,配置了事務,這樣在使用getCurrentSession時,只需要在方法上加上@Transcational註解即可,需要注意的是,不管你執行什麼操作,哪怕是查詢,你依然需要事務的控制。這跟上一篇提到的只有進行DDL才需要事務是兩個概念

jumpserver0.3.2版本開源跳板機系統部署

數據 mysqld cal arch enable roo 系統 ase 使用 1. 介紹 JumpServer亮點: 集成Ansible,批量執行命令; 支持WebTerminal wiki地址:https://github.com/jumpserver/jumps

Github使用之Pull Request的正確開啟方式如何在GitHub上貢獻開源專案

GitHub的官方幫助如下:        立topic branch),還有PullRequest的運作細節也沒有提到。寫個簡單的總結補充一下。 Step 1: Fork原專案        這個不解釋了,單擊一下滑鼠就能做到的事

阿里雲播放器SDK的正確開啟方式 | 功能、架構與應用

阿里雲播放器SDK(ApsaraVideo for Player SDK)是阿里視訊雲端到雲到端服務的重要一環,除了支援點播和直播的基礎播放功能外,還深度融合視訊雲業務,支援視訊的加密播放、安全下載、首屏秒開、低延時等業務場景,為使用者提供簡單、快速、安全、穩定的視訊播放

Pull Request的正確開啟方式如何在GitHub上貢獻開源專案

GitHub的官方幫助如下: 發現這個官方文件寫得比較簡單,並沒有提到開源專案協作方式的一些必要的trick(比如建立topic branch),還有PullRequest的運作細節也沒有提到。寫個簡單的總結補充一下。 Step 1: Fork原專案 這個不解釋了,單

Dubbo的正確開啟方式之基本介面定義異常處理

為什麼要寫這篇文章呢?因為公司在使用Dubbo時並沒有對Dubbo的用法做深入的瞭解,而是屬於拿來就用,隨著自己的想法來使用。這樣很不好,就像天龍八部的鳩摩智練習錯誤的六脈神劍一樣,方式不對,就容易走火入魔。下面是我近來在空閒時間對Dubbo的一些學習,也糾正了

【分享】WeX5的正確開啟方式3——繫結機制

今天整理一下WeX5的繫結機制。 原生的問題    假設我們做一個訂單系統,需要顯示商品單價,然後可以根據輸入數量計算出總價並顯示出來。使用原生程式碼也很容易實現,效果:           程式碼如下: <!--HTML code--> Price:

企業機器翻譯的正確開啟方式

近 20 年來,隨著網際網路的飛速發展,企業在新市場中開展業務變得更加容易。如今,客戶希望通過相同的採購流程在多個國家購買產品。網際網路、電子商務和移動電子商務的出現也推動著線上銷售的發展。 然而,新的機遇隨之產生了新的挑戰。 客戶不僅需要購買產品,可能還期望獲得售後支援、客戶服務和

雲邦互聯告訴你虛擬主機的正確開啟方式

【美國、韓國、俄羅斯、新加坡、香港 伺服器】行業觸底價 【海外伺服器租用 - 總有一款適合您】 雙至強5520 16核 24G記憶體 1TB 100M - 550元/月 E3-1220v3 4核 16G記憶體 1TB 100M - 650元/月 E3-1230v3 8核 8G記憶體 1TB 100M 5I

學習的正確開啟方式:不要一個人偷偷學習啦

學習的正確開啟方式:不要一個人偷偷學習啦 1.帶著你的朋友學,帶著你的女朋友男朋友來我們51CTO報班學習啦!!!2.帶著你的死黨閨蜜學,報班51CTO,閨蜜一起買買買,死黨一起挖金礦!!!3.老學員帶新學員,報班51CTO,讓我們一起徜徉在知識的海洋吧!!!   獎金幣(

《機器學習實戰》——python 中關於檔案讀取的正確開啟方式

    最近在學習《機器學習實戰》這本書,在做到裡面第08章的時候發生了一些小錯誤,具體內容如下:     資料總共有4177行,9列,最後一列為鮑魚的年齡,為標籤值,前8列為資料特徵,資料集中的資料長這個樣子:     在讀取資料

加溼器的正確開啟方式你有注意到這些點嗎?

又到了換季的季節了,這個時間恰恰是面板缺水的季節。我們每天都會感覺面板很乾,還總是起皮的。這時候,面板也非常的難受,還非常不好看。我們需要一臺加溼器來幫我們解決面板缺水的問題 加溼器能夠增加空氣溼度,使溼潤的空氣保持盎然生機,使肌膚滋潤,促進面部細胞血液迴圈和新陳代謝,從而舒緩神經緊張、消除疲勞

Mybatis原始碼正確開啟方式

精心挑選要閱讀的原始碼專案; 飲水思源——官方文件,先看文件再看原始碼; 下載原始碼,安裝到本地,保證能編譯執行; 從巨集觀到微觀,從整體到細節; 找到入口,抓主放次,梳理核心流程; 原始碼除錯,找到核心資料結構和關鍵類; 勤練習,多折騰;   MyBatis 原始碼下載地址:htt

轉型為一名資料科學家的正確開啟方式

                維基百科是你在資料科學領域解惑最佳的方式之一,但它所提供的資訊要麼就是特別簡單,要麼就是特別複雜。同樣的,在資料科學職業建議這方面也一樣:有些帖子針對的是初學者,有些則針對的是軟體工程師,亦或者是

四捨五入就用round( )?Python四捨五入的正確開啟方式

round( )函式簡介 菜鳥教程中介紹到,round() 函式作用就是,返回浮點數x的四捨五入值。 > round( x [, n] ) 引數x,n均為數值表示式,返回值為x的四捨五入值。n為保留的小數位數,不加n則只保留x四捨五入後的整數部分。 &

哈夫曼樹的正確開啟方式

1.哈夫曼樹畫法交流 假設一組權值節點如下,並畫出哈夫曼樹, (4,5,8,24,13,17,34) 畫哈夫曼樹的規則之一就是: 1.選出權值差值最小的兩個節點互為兄弟節點(即4,5互為兄弟節點) 2.合併後把他們的父節點權值(即:9)帶入到原佇列中和其他節點進

TensorFlow中RNN實現的正確開啟方式

2018年11月07日 20:09:13 杲昃 閱讀數:3 個人分類: NLP

InnoDB緩衝池預載入在MySQL 5.7中的正確開啟方式

DBAplus社群譯者:徐肖霞(新炬網路DBA工程師) 譯文稽核:葛雲傑 在這篇文章裡,我將討論在MySQL 5.7裡如何使用InnoDB緩衝池預載入特性。 從MySQL 5.6開始,可以配置MySQL儲存InnoDB快取池的資料,並在啟動時載入。在MySQL 5.7後,這是預設行為。在預設配置中,

VFS玻璃和水材質的正確開啟方式快來Get!

作者:Final(活力網) 前言: 效果圖當中出現大面積的水和比例材質,會增加畫面的通透性,和其他材質會有明顯的區別。在平時畫圖當中這兩個材質也是讓很多人頗為頭痛,也是老大難的問題。這一次詳細介紹一下這兩種材質的調法。 正文: 還是先交代一句,想要高質量的效果圖,把你苦心收藏

【程式設計師歸家計劃】放假回家之前拜伺服器?不存在的這才是保證程式設計師過好年的正確開啟方式

又到了一年中可以名正言順地“偷懶”的時候了,此時的正常情況是大家應該收一收努力工作和好好學習的心,準備過年了!這個階段幾乎所有的問題都可以用“過完年再說吧”和“剛過年,回頭再說”這樣的話語來抵擋,但是在網際網路界有這樣一群人,每次過年過節在歡慶中卻總帶著一絲焦慮,聚會時目