Spring 引导中的 spring.jpa.open-in-view=true 属性 是什么?
What is this spring.jpa.open-in-view=true property in Spring Boot?
我在 Spring JPA 配置的引导文档中看到 spring.jpa.open-in-view=true
属性。
- 这个 属性 的
true
默认值是不是根本没有提供?;
- 这到底有什么作用?我没有找到任何好的解释;
- 是否让您使用
SessionFactory
而不是 EntityManagerFactory
?如果是,我如何告诉它允许我改用 EntityManagerFactory
?
谢谢!
这个 属性 会注册一个 OpenEntityManagerInViewInterceptor
,它会注册一个 EntityManager
到当前线程,所以在网络请求完成之前你将拥有相同的 EntityManager
.它与 Hibernate SessionFactory
等无关
OSIV 反模式
不是让业务层决定如何最好地获取视图层所需的所有关联,OSIV(在视图中打开会话)强制持久性上下文保持打开状态,以便视图层可以触发Proxy初始化,如下图所示
OpenSessionInViewFilter
调用底层SessionFactory
的openSession
方法,得到一个新的Session
.
Session
绑定到 TransactionSynchronizationManager
。
OpenSessionInViewFilter
调用 javax.servlet.FilterChain
对象引用的 doFilter
并进一步处理请求
- 调用
DispatcherServlet
,并将 HTTP 请求路由到底层 PostController
。
PostController
调用 PostService
获取 Post
个实体的列表。
PostService
打开一个新事务,HibernateTransactionManager
重复使用 OpenSessionInViewFilter
打开的相同 Session
。
PostDAO
获取 Post
个实体的列表而不初始化任何惰性关联。
PostService
提交了底层事务,但是Session
没有关闭,因为它是从外部打开的。
DispatcherServlet
开始呈现 UI,后者依次导航惰性关联并触发它们的初始化。
OpenSessionInViewFilter
可以关闭Session
,同时释放底层数据库连接
乍一看,这似乎不是一件可怕的事情,但是,一旦从数据库的角度来看,一系列的缺陷就会开始变得更加明显。
服务层打开和关闭一个数据库事务,但之后,没有显式事务在进行。出于这个原因,从 UI 呈现阶段发出的每个附加语句都以自动提交模式执行。自动提交会给数据库服务器带来压力,因为每个事务都会在结束时发出提交,这会触发事务日志刷新到磁盘。一种优化是将 Connection
标记为只读,这将允许数据库服务器避免写入事务日志。
不再有关注点分离,因为语句是由服务层和 UI 呈现过程生成的。编写断言正在生成的语句数量的集成测试需要遍历所有层(Web、服务、DAO),同时将应用程序部署在 Web 容器上。即使在使用内存数据库(例如 HSQLDB)和轻量级 Web 服务器(例如 Jetty)时,这些集成测试的执行速度也会比分层分离且后端集成测试使用数据库的情况慢,而前端- 结束集成测试完全模拟了服务层。
UI 层仅限于导航关联,这反过来会触发 N+1 查询问题。尽管 Hibernate 提供 @BatchSize
for fetching associations in batches, and FetchMode.SUBSELECT
来应对这种情况,但注释会影响默认的提取计划,因此它们会应用于每个业务用例。出于这个原因,数据访问层查询更合适,因为它可以根据当前用例数据获取要求进行定制。
最后但并非最不重要的一点是,数据库连接在整个 UI 呈现阶段保持不变,这会增加连接租用时间并由于数据库连接池拥塞而限制整体事务吞吐量。连接保持得越多,等待从池中获取连接的其他并发请求就越多。
Spring 引导和 OSIV
不幸的是,OSIV (Open Session in View) is enabled by default in Spring Boot,从性能和可扩展性的角度来看,OSIV 确实是个坏主意。
因此,请确保在 application.properties
配置文件中有以下条目:
spring.jpa.open-in-view=false
这将禁用 OSIV,以便您可以正确处理 LazyInitializationException
。
从 2.0 版开始,Spring 引导问题 a warning when OSIV 默认启用,因此您可以在它影响生产系统之前很久就发现这个问题。
可能晚了,但我试图深入了解将其关闭与打开的含义,我发现这篇文章很有用 spring-open-session-in-view
希望这可以帮助某人...
我在 Spring JPA 配置的引导文档中看到 spring.jpa.open-in-view=true
属性。
- 这个 属性 的
true
默认值是不是根本没有提供?; - 这到底有什么作用?我没有找到任何好的解释;
- 是否让您使用
SessionFactory
而不是EntityManagerFactory
?如果是,我如何告诉它允许我改用EntityManagerFactory
?
谢谢!
这个 属性 会注册一个 OpenEntityManagerInViewInterceptor
,它会注册一个 EntityManager
到当前线程,所以在网络请求完成之前你将拥有相同的 EntityManager
.它与 Hibernate SessionFactory
等无关
OSIV 反模式
不是让业务层决定如何最好地获取视图层所需的所有关联,OSIV(在视图中打开会话)强制持久性上下文保持打开状态,以便视图层可以触发Proxy初始化,如下图所示
OpenSessionInViewFilter
调用底层SessionFactory
的openSession
方法,得到一个新的Session
.Session
绑定到TransactionSynchronizationManager
。OpenSessionInViewFilter
调用javax.servlet.FilterChain
对象引用的doFilter
并进一步处理请求- 调用
DispatcherServlet
,并将 HTTP 请求路由到底层PostController
。 PostController
调用PostService
获取Post
个实体的列表。PostService
打开一个新事务,HibernateTransactionManager
重复使用OpenSessionInViewFilter
打开的相同Session
。PostDAO
获取Post
个实体的列表而不初始化任何惰性关联。PostService
提交了底层事务,但是Session
没有关闭,因为它是从外部打开的。DispatcherServlet
开始呈现 UI,后者依次导航惰性关联并触发它们的初始化。OpenSessionInViewFilter
可以关闭Session
,同时释放底层数据库连接
乍一看,这似乎不是一件可怕的事情,但是,一旦从数据库的角度来看,一系列的缺陷就会开始变得更加明显。
服务层打开和关闭一个数据库事务,但之后,没有显式事务在进行。出于这个原因,从 UI 呈现阶段发出的每个附加语句都以自动提交模式执行。自动提交会给数据库服务器带来压力,因为每个事务都会在结束时发出提交,这会触发事务日志刷新到磁盘。一种优化是将 Connection
标记为只读,这将允许数据库服务器避免写入事务日志。
不再有关注点分离,因为语句是由服务层和 UI 呈现过程生成的。编写断言正在生成的语句数量的集成测试需要遍历所有层(Web、服务、DAO),同时将应用程序部署在 Web 容器上。即使在使用内存数据库(例如 HSQLDB)和轻量级 Web 服务器(例如 Jetty)时,这些集成测试的执行速度也会比分层分离且后端集成测试使用数据库的情况慢,而前端- 结束集成测试完全模拟了服务层。
UI 层仅限于导航关联,这反过来会触发 N+1 查询问题。尽管 Hibernate 提供 @BatchSize
for fetching associations in batches, and FetchMode.SUBSELECT
来应对这种情况,但注释会影响默认的提取计划,因此它们会应用于每个业务用例。出于这个原因,数据访问层查询更合适,因为它可以根据当前用例数据获取要求进行定制。
最后但并非最不重要的一点是,数据库连接在整个 UI 呈现阶段保持不变,这会增加连接租用时间并由于数据库连接池拥塞而限制整体事务吞吐量。连接保持得越多,等待从池中获取连接的其他并发请求就越多。
Spring 引导和 OSIV
不幸的是,OSIV (Open Session in View) is enabled by default in Spring Boot,从性能和可扩展性的角度来看,OSIV 确实是个坏主意。
因此,请确保在 application.properties
配置文件中有以下条目:
spring.jpa.open-in-view=false
这将禁用 OSIV,以便您可以正确处理 LazyInitializationException
。
从 2.0 版开始,Spring 引导问题 a warning when OSIV 默认启用,因此您可以在它影响生产系统之前很久就发现这个问题。
可能晚了,但我试图深入了解将其关闭与打开的含义,我发现这篇文章很有用 spring-open-session-in-view
希望这可以帮助某人...