比如在同一線程內用同一個session。在同一方法內用同一session,這樣我們就能夠用session里面緩存好的數據。但。我想說的不是緩存,且聽我一一道來。
近期試用spring3.0.2+struts2.18+hibernate3.3.2學習搭建一個web項目,出現了一個相當郁悶的問題。
就是我明明配置好了spring管理hibernate事務了,當我在dao中運行hibernate的方法時。如save。delete,update,createQuery,總是說不能在沒有活動的事務中運行(org.hibernate.HibernateException: createSQLQuery is not valid without active transaction)。立刻上google查。一無所獲。曾幾度懷疑是否配置寫出了。dao或service寫錯了,改來改去的依然存在問題。當時相當郁悶啊,想啊,你spring不是幫我管理事務么?你不自己主動開啟事務啊,還要我手動開啟啊。立刻查spring文檔。從中文到英文。沒發現什么有參考價值的線索,真是相當的打擊。代碼亂改一通。發現用spring的hibernatetemplate來進行數據操作又正常無比。不死心的去查了hibernate的doc,一個不留神給哥發現了一個冗長的配置屬性:hibernate.current_session_context_class。心里巨爽無比,就是你丫啦。小樣的。哥把你滅了。
hibernate.current_session_context_class是做什么用的呢?通俗點來講。就是配置session綁定到某一執行環境,比如從同一個線程中用getCurrentSession()取得的session都是同一個。當前沒有session就自己主動創建一個返回給你丫用。問題就出在這里了。官方文檔例如以下說: 使用 Hibernate 的大多數應用程序須要某種形式的“上下文相關的”會話。特定的會話在整個特
定的上下文范圍內始終有效。然而,對不同類型的應用程序而言,要為什么是組成這種“上下文”下一個定義一般是困難的。不同的上下文對“當前”這個概念定義了不同的范圍。在 3.0 版本號之前,使用 Hibernate 的程序要么採用自行編寫的基於 ThreadLocal 的上下文會話。要么採用HibernateUtil 這種輔助類,要么採用第三方框架(比方 Spring 或 Pico),它們提供了基於代理(proxy)或者基於攔截器(interception)的上下文相關的會話。
從 3.0.1 版本號開始,Hibernate 添加了SessionFactory.getCurrentSession() 方法。
一開始,它假定了採用 JTA 事務。JTA 事務定義了當前 session 的范圍和上下文(scope 和 context)。由於有好幾個獨立的 JTA TransactionManager 實現穩定可用,不論是否被部署到一個 J2EE 容器中,大多數(假若不是全部的)應用程序都應該採用 JTA 事務管理。基於這一點。採用 JTA 的上下文相關的會話能夠滿足你一切須要。
再來看我的配置,講hibernate.current_session_context_class的值設成thread。
按我簡單的理解就是將getCurrentSession()返回的session綁定到當前執行線程中。比較專業的說法是此session的上下文是thread,但不是spring已經托管的那個Session對象。再用哥那大腿想了幾下,瞬間了解了一些。所以獲取的session是在spring代理的上下文之外的的當前線程之中。所以此session並不是事務管理器代理的那個session,不會自己主動開啟事務。依據官方提示:第三方框架提供了基於代理(proxy)或者基於攔截器(interception)的上下文相關的會話的管理,所以把hibernate.current_session_context_class設置刪除了。一切又回到當初風平浪靜的日子了。
參考http://justsee.iteye.com/blog/1061576,最終了解這個問題的前因后果。摘錄例如以下:
在ssh2中的sessionFactory配置文件里應將hibernate.current_session_context_class設為org.springframework.orm.hibernate3.SpringSessionContext(默覺得此值)。並應用spring管理事務。
假設為<prop key="hibernate.current_session_context_class">thread</prop> 則會報異常,
原因還是spring中hibernate.current_session_context_class的問題
在spring的類LocalSessionFactoryBean源代碼。方法buildSessionFactory中將hibernate.current_session_context_class設為org.springframework.orm.hibernate3.SpringSessionContext
傳智播客成都java培訓中心:http://cd.itcast.cn?140831ls