Hibernate Lazy 載入問題的解決
今天在寫Spring+Hibernate的時候,遇到了Hibernate Lazy 載入的問題,後來經過調整配置解決了一個惱人的問題。現將解決方案和大家分享一下。
SEQBOOKID
Hbm檔案
org.hibernate.dialect.Oracle9Dialect
destroy-method="close">
Sping配置檔案
最開始的時候,服務程式碼是這樣寫的
public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem) getHibernateTemplate().load(
BookItem.class, new Long(bookItemId));
return bookItem;
}
JUNIT測試程式碼如下
public class BookItemRepositoryTest extends TestCase {
BookItemRepository bookItemRepo=null;
protected void setUp() throws Exception {
ApplicationContext context=new
ClassPathXmlApplicationContext("spring-context.xml");
bookItemRepo=(BookItemRepository)context.getBean("BookItemRepositoryImpl");
}
public void testFindById(){
BookItem item=bookItemRepo.findById(30);
assertEquals("123456", item.getBook().getISBN());
assertEquals("QiuHongBookStore", item.getBookStore().getName());
}
}
測試執行以後報下列錯誤
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
at domain.BookItem$$EnhancerByCGLIB$$2f924ddd.getBook(
at test.domain.repository.hibernate.BookItemRepositoryTest.testFindById(BookItemRepositoryTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
開始我在HBM檔案中,把
然後就正常了。但是這樣的代價是取消延遲載入,在load的時候直接進行載入。如果這樣的話,在物件很大的時候效能會很差。於是在網上查資料。這個主要是HibernateTemplate在載入的時候,採用是lazy 載入方法,因為HibernateTemplat 在load完成後自動的關閉了Session,所以造成了LazyInitializationException異常。
我最開始將程式碼改成如下,也能解決這個問題。
public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem)getSession().load(
BookItem.class, new Long(bookItemId));
return bookItem;
}
但是這樣改我心裡面沒有地,我擔心會不會存在Session沒有關閉或者洩漏的問題。
後來我聯想如果在Spring中增加事務控制,那麼HibernateTemplate是不是就不會在呼叫完成後馬上Close Session了呢?(如果Close了Session,那事務是不是都需要Commit或RollBack了呢?,那這樣的話還談什麼事務控制呢)。於是我進行了如下事務配置
然後程式碼也進行了修改,執行手工載入操作。
public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem) getHibernateTemplate().load(
BookItem.class, new Long(bookItemId));
getHibernateTemplate().initialize(bookItem); // 手工載入每個物件
getHibernateTemplate().initialize(bookItem.getBook()); // 手工載入每個物件
getHibernateTemplate().initialize(bookItem.getBookStore()); //手工載入每個物件
return bookItem;
}
再進行測試就OK了!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/90000/viewspace-1043221/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- hibernate 的lazy載入問題
- hibernate中lazy與二級快取問題快取
- Angular Component 延遲載入 Lazy Load 的一個依賴注入的問題以及解決方案Angular依賴注入
- hibernate 1 + N 問題解決
- spring註解@lazy,bean懶載入SpringBean
- 解決ionic 2載入速度慢的問題
- 載入不同位置hibernate包產生的問題
- vue-view-lazy:基於vue2.x懶載入解決方案VueView
- 解決 goland 載入 golang.org 包的網路問題GoLandGolang
- 解決建立SpringBoot工程載入較慢的問題Spring Boot
- 懶載入(lazy loading)
- gitbook 入門教程之解決windows熱載入失敗問題GitWindows
- listView懶載入解決快速拖動卡屏問題View
- 利用 Arthas 解決啟動 StandbyNameNode 載入 EditLog 慢的問題
- SSH登入很慢問題的解決
- 奇怪的登入問題及解決
- 解決ssh登入慢的問題
- 在Hibernate中使用Lazy="false" 的困惑False
- Android之批量載入圖片OOM問題解決方案AndroidOOM
- VIM Lazy Load 懶載入/延遲載入技術
- 解決「問題」,不要解決問題
- 解決Spring Data JPA Hibernate的N+1問題的最佳方法Spring
- Composer 下載較慢的問題解決
- 解決 macOS HomeBrew 下載緩慢的問題Mac
- 使用tengine解決負載均衡的session問題負載Session
- 解決問題的8個步驟-轉載
- android中webView載入H5,JS不能呼叫問題的解決AndroidWebViewH5JS
- vue-router懶載入速度緩慢問題及解決方法Vue
- AngularJS進階(三十八)上拉載入問題解決方法AngularJS
- 討論TableLayoutPanel載入緩慢和閃爍問題解決方案
- hibernate懶載入
- 解決ArcGIS API for Silverlight 載入地圖的內外網訪問問題API地圖
- lvs 負載均衡遇到的一個問題. (問題解決)負載
- 解決VNC有些鍵不能輸入的問題VNC
- Hibernate的session問題Session
- 微信登入-6問題解決方案
- 解決Mysql匯入亂碼問題MySql
- ssh登入慢問題解決方法