Spring的OpenEntityManagerInViewFilter

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

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

ervice{ 
        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层调用结束后才关闭,


如果发现配置完以后不起作用,请看另外一篇博客:http://whoosh.iteye.com/admin/blogs/1154924

Spring针对Hibernate的非JPA实现用的是OpenSessionInViewFilter,原理与这个大同小异。用了这类Filter以后会降低一定的运行效率,但是一般的web项目都会加入一些开源的缓存管理框架,这样一来,对效率的影响就变得很小了。


你可能感兴趣的:(spring)