Closed. This question is opinion-based。它当前不接受答案。












想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。

7年前关闭。



Improve this question




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

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

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

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

创建自定义查询:创建针对延迟加载的查询和针对急切加载的查询。此解决方案实际上有效,但是在我看来,延迟加载模式的错误应用

最佳答案

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

在呈现开始之前,将刷新 session ,提交事务并关闭 session 。

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

另一种方法是在 View 中使用打开的 session ,该 session 在渲染时保持打开状态,但是由于意外使用延迟加载,可能会在应用程序中引起N + 1问题。

另外, View 中的开放 session 可能会导致不可重复读取的问题,其中一些数据已由服务层读取并用于提交事务,但是当 View 呈现开始时,该数据将不再可用或已被修改,这对于建立 View 。

有关如何使用OSIV的这些问题,请参见JBoss Seam团队的post(Seam是与Hibernate相同的开发人员开发的)。

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

如果由于应用程序例如对性能至关重要,因此重点放在控制查询上,则可以选择自定义查询。

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

07-27 13:45