java - 延迟加载处理(Hibernate + Spring MVC)

标签 java spring hibernate spring-mvc

<分区>

在 Spring MVC 应用程序中处理延迟加载对象的最佳解决方案是什么?我已经对这个主题进行了一些搜索,并且找到了以下解决方案:

在 View 中打开 session :为每个请求打开一个 session ,并在 View 呈现后关闭它。这个解决方案的问题是我还需要在 Spring MVC 模型之外延迟加载对象(例如 Junit 测试用例)。关于此解决方案的另一个讨论问题是异常处理。如果事务在 View 渲染期间抛出异常怎么办?

显式打开 session :每当我需要延迟加载对象时,显式打开 session 。实际上这个解决方案应该可行,但我认为这不是正确的方法。

使用 AOP: 创建一个将延迟加载方法包装在 session 中的方面。这可能是一个解决方案,但我不知道我应该在我的应用程序的哪个级别定义 poitcuts

创建自定义查询:创建延迟加载查询和预加载查询。这个解决方案确实有效,但在我看来是延迟加载模式的错误应用

最佳答案

没有在所有情况下总是更好的解决方案,问题是服务层上的 @Transactional 不会在渲染阶段开始时保持 session 打开。

在渲染开始之前刷新 session ,提交事务并关闭 session 。

解决此问题的一种方法是使用自定义查询,根据正在构建的 View 加载每时每刻所需的数据。

另一种方法是在 View 中使用open session,这会在渲染时保持session打开,但可能会由于无意中使用延迟加载而导致应用程序出现N+1问题。

同时在 View 中打开 session 可能会导致不可重复读取的问题,其中一些数据被服务层读取并用于提交事务,但是当 View 渲染开始时该数据不再可用或被修改,并且它对于构建 View 很重要。

查看此 post来自 JBoss Seam 团队的关于使用 OSIV 的文章经历了这些问题(Seam 是我和 Hibernate 的许多相同开发人员开发的)。

不同的方法有不同的优缺点,具体取决于项目的优先级。如果不必编写自定义查询的便利性很重要,因为要编写许多查询,那么 OSIV 是一个不错的选择。偶尔出现的 N+1 问题可以逐案解决并忍受。

如果因为应用程序对性能至关重要而强调控制查询,那么自定义查询是一种选择。

确实没有明确的最佳解决方案。如果您使用在客户端(例如 angular.js)而不是服务器端运行的 View 技术,那么您就不会遇到这类问题,因为不涉及服务器端渲染。

关于java - 延迟加载处理(Hibernate + Spring MVC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21336967/

相关文章:

java - 无法在azure windows vm上使用application Insights代理启动java spring boot应用程序

java - 将多对多关系保存在相应的映射表中

java - 删除父项将子值设置为 NULL 而不删除它们

java - 如何为我正在上传的文件指定一个随机文件名?

java - 当 Web 服务器线程中出现 OutOfMemoryError 时,Spring 启动请求会挂起

java - Files.delete 和 Files.deleteIfExists 的行为有点奇怪

java - 如何调试这段java代码?该代码旨在获取Linux系统中的CPU使用率和内存信息

java - 如果无法获取锁,Hibernate LockMode 释放并快速失败

java - 模拟 FeignClient 响应

java - ArrayList 中的 set()