在视图模式中打开会话 [英] Open Session In View Pattern

查看:145
本文介绍了在视图模式中打开会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我选择的JPA开发框架(Hibernate实现),Spring和< insert MVC框架 - Struts 1,Struts 2,Spring MVC,Stripes ...>。 p>

我一直在思考我实体层中的关系 - 例如我有一个有很多订单行的订单实体。我设置了我的应用程序,以便它急切地加载每个订单的订单行。你认为这是一个懒惰的方法来解决懒惰的初始化问题,如果我把撷取策略设置为false,我会遇到的?



我看到的方式在检索实体及其关联时,我有以下替代方法:


  1. 使用Open Session In View模式创建会话在每个请求之前提交事务并返回响应。


  2. 实现一个DTO(数据传输对象)层,使得我执行的每个DAO查询返回正确初始化DTO为我的目的我不太喜欢这个选项,因为在我的经验中,我发现它创建了大量的样板复制代码,并且变得混乱维护。


  3. 不要映射JPA中的任何关联,以便我执行的每个查询只返回我感兴趣的实体 - 这可能需要我有DTO,并且会很难维护,我认为不符合ORM的目的首先,


  4. 急于获取所有(或大多数关联) - 在上面的示例中,在检索订单时总是获取所有订单行。


所以我的问题是,什么时候和在什么情况下你会使用哪些选项?你总是坚持一种方式吗?



我会问一位同事,但我认为,如果我甚至提到开放会议在视图,我会迎接了空白的盯着:(我真正在寻找的是一些高级或非常有经验的开发人员的一些建议。



谢谢你们!

解决方案

我已经成功地解决了Open Session In View中的所有懒惰初始化问题(即Spring实现),我使用的技术是确切的



使用此模式可以让我完全映射实体关系,而不用担心在dao中获取子实体,在90%的情况下该模式解决了视图中的懒惰初始化需求,在某些情况下,您必须手动初始化关系,这些情况很少见,在我的情况下总是涉及非常复杂的映射。



在V中使用Open Entity Manager时iew模式重要的是定义实体关系,特别是传播和事务设置。如果这些配置不正确,当某些实体在视图中被懒惰初始化时,将会发生与已关闭会话相关的错误,并且由于会话已关闭已经失败。



我一定会选择选项1.选项2可能需要有时,但我看到绝对没有理由使用选项3.选项4也是一个否。热切地提取所有内容会杀死任何需要列出一些父实体的几个属性(tis case中的命令)的视图。



N + 1选择



在开发过程中,由于在视图中初始化某些关系,将会有N + 1个选择。但这不是放弃模式的理由。只要解决这些问题,并将代码交付给生产。使用OEMIV模式来解决这些问题也是一样简单:添加适当的dao或服务方法,修复控制器来调用不同的finder方法,或者添加一个视图到数据库等。


I'm asking this question given my chosen development frameworks of JPA (Hibernate implementation of), Spring, and <insert MVC framework here - Struts 1, Struts 2, Spring MVC, Stripes...>.

I've been thinking a bit about relationships in my entity layer - for example I have an order entity that has many order lines. I've set up my app so that it eagerly loads the order lines for every order. Do you think this is a lazy way to get around the lazy initialization problems that I would come across if I was to set the fetch strategy to false?

The way I see it, I have the following alternatives when retrieving entities and their associations:

  1. Use the Open Session In View pattern to create the session on each request and commit the transaction before returning the response.

  2. Implement a DTO (Data Transfer Object) layer such that every DAO query I execute returns the correctly initialized DTO for my purposes. I don't really like this option much because in my experience I've found that it creates a lot of boilerplate copying code and becomes messy to maintain.

  3. Don't map any associations in JPA so that every query I execute returns only the entities I'm interested in - this will probably require me to have DTOs anyway and will be a pain to maintain and I think defeats the purpose of having an ORM in the first place.

  4. Eagerly fetch all (or most associations) - in the example above, always fetch all order lines when I retrieve an order.

So my question is, when and under what circumstances would you use which of these options? Do you always stick with one way of doing it?

I would ask a colleague but I think that if I even mentioned the term 'Open Session in View' I would be greeted with blank stares :( What I'm really looking for here is some advice from a senior or very experienced developer.

Thanks guys!

解决方案

I've successfully solved all my lazy initialization problems with Open Session In View -pattern (ie. the Spring implementation). The technologies I used were the exact same as you have.

Using this pattern allows me to fully map the entity relationships and not worry about fetching child entities in the dao. Mostly. In 90% of the cases the pattern solves the lazy initialization needs in the view. In some cases you'll have to "manually" initialize relationships. These cases were rare and always involved very very complex mappings in my case.

When using Open Entity Manager In View pattern it's important to define the entity relationships and especially propagation and transactional settings correctly. If these are not configured properly, there will be errors related to closed sessions when some entity is lazily initialized in the view and it fails due to the session having been closed already.

I definately would go with option 1. Option 2 might be needed sometimes, but I see absolutely no reason to use option 3. Option 4 is also a no no. Eagerly fetching everything kills the performance of any view that needs to list just a few properties of some parent entities (orders in tis case).

N+1 Selects

During development there will be N+1 selects as a result of initializing some relationships in the view. But this is not a reason to discard the pattern. Just fix these problems as they arise and before delivering the code to production. It's as easy to fix these problems with OEMIV pattern as it's with any other pattern: add the proper dao or service methods, fix the controller to call a different finder method, maybe add a view to the database etc.

这篇关于在视图模式中打开会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆