web.xml中openEntityManagerInViewFilter的做用(轉)


  <span style="font-size:18px;"><!-- Open Entity Manager in View filter-->  
  1.     <filter>  
  2.         <filter-name>openEntityManagerInViewFilter</filter-name>  
  3.         <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>openEntityManagerInViewFilter</filter-name>  
  7.         <url-pattern>/*</url-pattern>  
  8.     </filter-mapping></span>  

 

Java Web項目中使用Hibernate常常會遇到LazyInitializationException。這是由於controller和model層(java代碼)將經過JPA的一些啓用了延遲加載功能的領域(如用getRefrence()方法或者在關聯關係中採用fetch=FetchType.LAZY)返回給view層(jsp代碼)的時候,因爲加載領域對象的JPA Session已經關閉,致使這些延遲加載的數據訪問異常。html

這時就能夠使用OpenEntityManagerInViewFilter來將一個JPAsession與一次完整的請求過程對應的線程相綁定。請看一段僞代碼:java

 

 
  1. Service{    
  2.         entitymanager=context.getEntityManager();    
  3.         if(entitymanager==null) context.put(factory,createEntityManager());    
  4.         entitymangager=context.getEntityManager();    
  5.         entitymanager.begin();    
  6.         public void find(Integer productid){//除了這個方法外,其餘都是經過AOP織入的    
  7.             em.getReference(Product.class,productid));    
  8.         }    
  9.         entitymanager=context.getEntityManager();    
  10.         entitymanager.commit();    
  11.         entitymanager.close();    
  12. }    

上面的僞代碼演示了若是咱們想調用咱們本身定義的一個find()方法,spring會在該方法的先後織入一些代碼來開始事物和關閉session。當view層調要用這個find()方法獲取的對象(因爲採用了延遲加載模式,只有到要使用到該對象的時候纔會讓session去數據庫取)的時候,實際上session已經關閉了,不能再讓session獲取對象。spring

 

OpenEntityManagerInViewFilter會讓session一直到view層調用結束後才關閉,請看下面的僞代碼:數據庫

[html]  view plain  copy
 
  1. Filter{    
  2.         doFilter(chain){    
  3.             context.getEntityManager().open();    
  4.             chain.doFilter(req,res){    
  5.                 xxxAction{    
  6.                     execute(){    
  7.                         Product product=service.find(productid);//此時該對象爲遊離狀態,實際上並無在數據庫得到值。    
  8.                         req.setAttibute("Product",produxt);//這時候纔到數據庫裏面去取值    
  9.                         return mapping.findForward("product");    
  10.                     }    
  11.                 }    
  12.             }    
  13.             context.getEntityManager().close()...    
  14.         }    
  15.     }    


若是沒使用OpenEntityManagerInViewFilter,session會在service.find()方法後就被關閉,用了之後session在整個view層結束後才關閉。session

摘自:http://whoosh.iteye.com/blog/1300721app

相關文章
相關標籤/搜索