標籤:close targe try get 資源 初步 blank 執行 rollback
什麼是OpenSessionInView?
在hibernate中使用load方法時,並未把資料真正擷取時就關閉了session,當我們真正想擷取資料時會迫使load載入資料,而此時session已關閉,所以就會出現異常。
比較典型的是在MVC模式中,我們在M層調用持久層擷取資料時(持久層用的是load方法載入資料),當這一調用結束時,session隨之關閉,而我們希望在V層使用這些資料,這時才會迫使load載入資料,我們就希望這時的session是open著得,這就是所謂的Open Session In view 。 我們可以filter來達到此目的。下面的代碼初步解決了此問題:
1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { 2 Session session=null; 3 Transaction tx=null; 4 try{ 5 session=HibernateUtil.getCurrentSession(); 6 tx=session.beginTransaction();//開啟事務 7 chain.doFilter(request, response); //傳遞給下一個filter,如果沒有就是請求的資源。 8 tx.commit();//走完一圈回來提交事務 9 10 }catch(Exception e){11 if(tx!=null){12 tx.rollback();//出現異常,復原事務13 }14 throw new RuntimeException(e.getMessage());15 }finally{16 HibernateUtil.closeCurrentSession();17 }18 19 }
簡析:當請求到達時,會首先被此攔截器攔截,當資料經過擷取並在V層顯示完畢後,回到此Filter內部,此時提交事務-->關閉session。
關於chain.doFilter(request,response)
他的作用是將請求轉寄給過濾器鏈上下一個對象。這裡的下一個指的是下一個filter,如果沒有filter那就是你請求的資源。
走完這一圈才是一次請求的過程,再次回來後再執行chain.doFilter後面的語句。
它將session的範圍擴大。所以原本在業務層中開啟session改為在filter中開啟,同時後面使用session的時候必須要用
getCurrentSession的方式,也不用再使用事務、提交這些操作,因為這些統一由filter完成。:
缺點是:session會因此關閉延時。
Hibernate(九)__OpenSessionInView解決懶載入問題