Java spring引导中的spring.jpa.open in view=true属性是什么?

Java spring引导中的spring.jpa.open in view=true属性是什么?,java,spring,jpa,spring-boot,spring-data,Java,Spring,Jpa,Spring Boot,Spring Data,我在spring引导文档中看到了jpa配置的spring.jpa.openin view=true属性 如果未提供该属性的默认值,则该属性的值是否为true值 这到底有什么用?我没有找到任何好的解释 它是否使您使用SessionFactory而不是EntityManagerFactory?如果是,我如何告诉它允许我使用EntityManagerFactory 谢谢 此属性将注册一个OpenEntityManagerInViewInterceptor,它将EntityManager注册到当前线

我在spring引导文档中看到了jpa配置的
spring.jpa.openin view=true
属性

  • 如果未提供该属性的默认值,则该属性的
    值是否为true
  • 这到底有什么用?我没有找到任何好的解释
  • 它是否使您使用
    SessionFactory
    而不是
    EntityManagerFactory
    ?如果是,我如何告诉它允许我使用
    EntityManagerFactory

谢谢

此属性将注册一个
OpenEntityManagerInViewInterceptor
,它将
EntityManager
注册到当前线程,因此在web请求完成之前,您将拥有相同的
EntityManager
。它与Hibernate
SessionFactory等无关。

OSIV反模式 OSIV(视图中的开放会话)不让业务层决定如何最好地获取视图层所需的所有关联,而是强制持久性上下文保持打开状态,以便视图层可以触发代理初始化,如下图所示

  • OpenSessionInViewFilter
    调用底层
    SessionFactory
    openSession
    方法,并获得一个新的
    会话
  • 会话
    已绑定到
  • OpenSessionInViewFilter
    调用
    javax.servlet.FilterChain
    对象引用的
    doFilter
    ,并进一步处理请求
  • 调用,它将HTTP请求路由到底层的
    PostController
  • PostController
    调用
    PostService
    以获取
    Post
    实体的列表
  • PostService
    打开一个新事务,
    hibernatTransactionManager
    重用由
    OpenSessionInViewFilter
    打开的相同的
    会话
  • PostDAO
    获取
    Post
    实体的列表,而不初始化任何延迟关联
  • PostService
    提交基础事务,但是
    会话
    未关闭,因为它是在外部打开的
  • DispatcherServlet
    开始呈现UI,UI反过来导航惰性关联并触发它们的初始化
  • OpenSessionInViewFilter
    可以关闭
    会话
    ,并释放底层数据库连接
乍一看,这看起来并不是一件可怕的事情,但是,一旦您从数据库的角度来看它,一系列的缺陷开始变得更加明显

服务层打开和关闭一个数据库事务,但之后,没有显式事务进行。因此,从UI呈现阶段发出的每个附加语句都以自动提交模式执行。自动提交给数据库服务器带来了压力,因为每个事务在结束时都会发出提交,这会触发事务日志刷新到磁盘。一种优化方法是将
连接标记为只读,这将允许数据库服务器避免写入事务日志

不再存在关注点分离,因为语句是由服务层和UI呈现过程生成的。编写断言所生成语句数量的集成测试需要遍历所有层(web、服务、DAO),同时将应用程序部署在web容器上。即使在使用内存数据库(如HSQLDB)和轻量级Web服务器(如Jetty)时,这些集成测试的执行速度也会比分层和后端集成测试使用数据库时慢,而前端集成测试完全模拟服务层

UI层仅限于导航关联,这反过来会触发N+1查询问题。尽管Hibernate提供了批量获取关联的功能,并且为了应对这种情况,注释会影响默认的获取计划,因此它们会应用于每个业务用例。因此,数据访问层查询更合适,因为它可以根据当前用例数据获取需求进行定制

最后但并非最不重要的一点是,数据库连接在整个UI呈现阶段保持,这会增加连接租用时间,并由于数据库连接池上的拥塞而限制总体事务吞吐量。连接保持得越多,等待从池中获取连接的其他并发请求就越多

弹簧靴和OSIV 不幸的是,从性能和可伸缩性的角度来看,OSIV确实是个坏主意

因此,请确保在
应用程序.properties
配置文件中有以下条目:

spring.jpa.open-in-view=false
这将禁用OSIV,以便以正确的方式处理
LazyInitializationException


从2.0版开始,Spring引导问题在默认情况下处于启用状态,因此您可以在影响生产系统之前很久就发现此问题。

目前,我使用筛选器OpenEntityManager视图筛选器控制EntityManager,直到web请求完成。您指的这个拦截器“OpenEntityManagerViewInterceptor”与“OpenEntityManagerViewFilter”相同吗?他们之间有什么区别?因此,我不会在Spring引导的servlet上下文中使用更多的过滤器?只有在Spring中使用DispatcherServlet时,拦截器才起作用(因为拦截器是Spring机制)。该过滤器可以映射到所有配置的servlet(我们在一个应用程序中将其用于FacesServlet)。因此,如果只使用DispatcherServlet,则可以添加属性并删除筛选器,o