web.xml中openEntityManagerInViewFilter的作用


	
		openEntityManagerInViewFilter
		org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
	
	
		openEntityManagerInViewFilter
		/*
	

在Java Web项目中使用Hibernate经常会遇到LazyInitializationException。这是因为controller和model层(java代码)将通过JPA的一些启用了延迟加载功能的领域(如用getRefrence()方法或者在关联关系中采用fetch=FetchType.LAZY)返回给view层(jsp代码)的时候,由于加载领域对象的JPA Session已经关闭,导致这些延迟加载的数据访问异常。

这时就可以使用OpenEntityManagerInViewFilter来将一个JPAsession与一次完整的请求过程对应的线程相绑定。请看一段伪代码:


    Service{  
            entitymanager=context.getEntityManager();  
            if(entitymanager==null) context.put(factory,createEntityManager());  
            entitymangager=context.getEntityManager();  
            entitymanager.begin();  
            public void find(Integer productid){//除了这个方法外,其他都是通过AOP织入的  
                em.getReference(Product.class,productid));  
            }  
            entitymanager=context.getEntityManager();  
            entitymanager.commit();  
            entitymanager.close();  
    }  
上面的伪代码演示了如果我们想调用我们自己定义的一个find()方法,spring会在该方法的前后织入一些代码来开始事物和关闭session。当view层调要用这个find()方法获取的对象(由于采用了延迟加载模式,只有到要使用到该对象的时候才会让session去数据库取)的时候,实际上session已经关闭了,不能再让session获取对象。

OpenEntityManagerInViewFilter会让session一直到view层调用结束后才关闭,请看下面的伪代码:

    Filter{  
            doFilter(chain){  
                context.getEntityManager().open();  
                chain.doFilter(req,res){  
                    xxxAction{  
                        execute(){  
                            Product product=service.find(productid);//此时该对象为游离状态,实际上并没有在数据库获得值。  
                            req.setAttibute("Product",produxt);//这时候才到数据库里面去取值  
                            return mapping.findForward("product");  
                        }  
                    }  
                }  
                context.getEntityManager().close()...  
            }  
        }  

如果没使用OpenEntityManagerInViewFilter,session会在service.find()方法后就被关闭,用了以后session在整个view层结束后才关闭。

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




你可能感兴趣的:(java)