Java 在视图模式中打开会话
我问这个问题是因为我选择了JPA(Hibernate实现)、Spring和 我一直在思考实体层中的关系——例如,我有一个订单实体,它有许多订单行。我已经设置了我的应用程序,以便它能够急切地加载每个订单的订单行。如果我将fetch策略设置为false,您是否认为这是一种解决延迟初始化问题的懒惰方法 在我看来,在检索实体及其关联时,我有以下几种选择:Java 在视图模式中打开会话,java,design-patterns,session,orm,Java,Design Patterns,Session,Orm,我问这个问题是因为我选择了JPA(Hibernate实现)、Spring和 我一直在思考实体层中的关系——例如,我有一个订单实体,它有许多订单行。我已经设置了我的应用程序,以便它能够急切地加载每个订单的订单行。如果我将fetch策略设置为false,您是否认为这是一种解决延迟初始化问题的懒惰方法 在我看来,在检索实体及其关联时,我有以下几种选择: 使用视图中的开放会话模式在每个请求上创建会话,并在返回响应之前提交事务 实现一个DTO(数据传输对象)层,这样我执行的每个DAO查询都会返回正确初始化
谢谢大家!我已经用视图模式(即Spring实现)中的Open Session成功地解决了我所有的惰性初始化问题。我使用的技术与您完全相同 使用此模式可以完全映射实体关系,而不用担心在dao中获取子实体。大多数情况下,在90%的情况下,该模式解决了视图中的延迟初始化需求。在某些情况下,您必须“手动”初始化关系。在我的例子中,这些情况很少见,而且总是涉及非常复杂的映射 在视图模式中使用Open Entity Manager时,重要的是正确定义实体关系,尤其是传播和事务设置。如果未正确配置这些设置,则当某些实体在视图中延迟初始化并且由于会话已关闭而失败时,将出现与关闭会话相关的错误我已经被解雇了 我肯定会选择选项1。有时可能需要选项2,但我认为绝对没有理由使用选项3。选项4也是一个否定的选项。急切地获取所有内容会降低任何只需要列出某些父实体(在这种情况下为订单)的一些属性的视图的性能 N+1选择
在开发过程中,由于初始化视图中的某些关系,将有N+1个选择。但这不是放弃模式的理由。只要在出现这些问题时以及在将代码交付到生产环境之前解决这些问题就可以了。使用OEMIV模式解决这些问题就像使用任何其他模式一样简单:添加适当的dao或服务方法,修复控制器以调用不同的finder方法,可能会向数据库添加视图等。但DTO方法也有一些好处。您必须事先考虑您需要什么信息。在某些情况下,这将阻止您生成n+1 select语句。这也有助于了解在何处使用即时抓取和/or优化视图。视图中的打开会话存在一些问题 例如,如果事务失败,您可能在提交时就知道它太迟了,一旦您几乎完成了页面的呈现(可能是响应已经提交,所以您无法更改页面!)…如果您以前知道该错误,您可能会遵循不同的流程,并最终呈现不同的页面 另一个例子是,按需读取数据可能会导致许多“N+1选择”问题,从而影响性能
许多项目使用以下路径:
为了避免为DTO创建额外的类,您可以在实体对象本身内部加载数据“订单”和“订单”是否构成了大量的数据?他们是否参与了需要实时响应的在线过程?如果是这样的话,你可能会考虑不使用急切的获取——它确实在性能上产生了巨大的差异。如果数据量很小,那么急于获取就没有问题。 关于使用DTO,它可能是一个可行的实现。 如果您的业务层由您自己的应用程序(即一个小型web应用程序及其业务逻辑)在内部使用,那么最好在视图中使用您自己的实体和视图中的开放会话模式,因为它更简单 如果您的实体被许多应用程序(即在您的公司中提供服务的后端应用程序)使用,那么使用DTO会很有趣,因为您不会向您的客户公开您的模型。公开DTO可能意味着您将很难重构您的模型,因为它可能会