2013-01-16 65 views
7

纠正我,如果这是一个确切的重复,我知道这个话题经常讨论,但无法找到明确的答案。MVC With Lazy Loading

问题:

什么是一个Web应用程序的MVC处理休眠对象的最佳实践的解决方案?

细节:

我使用Hibernate和想去的地方可能利用延迟加载。
我正在使用MVC风格的webapp。
我讨厌获取懒加载初始化异常。
我讨厌在事务之间重新挂接Hibernate对象。

选项:

  1. 渴望负载一切
    • 解决了这一延迟初始化的问题,但让我查询更大
  2. 使用一些 '打开会话中查看' 概念
    • 我爱它的简单性
    • 对象仍然需要重新连接,并在AJAXy设置,相当频繁
    • 会话离开交易
      • 在似乎站不住脚之前打开的每个请求
    • “触摸”的项目,我需要最好的..和繁琐
  3. 创建不同的,简化的,“超脱”对象,所以认为不会看到真正的Hibernate对象
    • 钍ESE可能比完整的Hibernate对象更简单,所以它不喜欢这种型号
    • 我听说过这个建议的地方,但似乎只是更多的责任/代码的完全急切装载/工作
  4. 打开会话当我想与Hibernate对象进行交互时。
    • 这可以很好地包装在Spring服务层中,但有时似乎过多。例如:我想hibernateObject.getRelatedObjects()但需要说类似springService.getRelatedObjects(hibernateObject)

我这么想吗?
我有过度思考的东西吗?
我有没有想过的事情?

PS:

对于我使用ZK但真想ZK具体的答案Web框架。
我也使用Spring,并且很酷,并且Spring特定的答案是无处不在的。

回答

5

使用4-ish - 不要在视图中使用打开的会话,不要让hibernate实体一直冒泡到视图,而是让变换器在hibernate实体和域对象或'view bean'取决于你想如何工作。

我认为Hibernate实体只是一种持久性策略,而不是一种领域模型或UI表示。

+0

干杯Bedwyr,我想我会采取这种做法。这是更多的代码,但视图和模型的分离应该值得。 –

+0

我同意这个答案,并赞成它,只是想添加一个代码,你可能会发现得心应手。这是一台可变深度复印机,它依赖于Spring,但比像Dozer这样的完整贴图解决方案的重量更轻。 https://gist.github.com/thinkbigthings/5488327 – Jay

+0

此处还有一个Hibernate unproxifier:https:// gist。github.com/thinkbigthings/5141813 – Jay

1

混合表示层和数据访问层是一个设计问题。

您的视图应该通过控制器访问模型,但通过直接使用Hibernate对象来混合图层。 IMO数据访问应该是模型下的另一层。即使您的实体在xml中注释或定义,它们本身也与模型分离。

引入封装Hibernate逻辑并通过控制器的服务契约公开的Facade或Manager,返回代表这些实体的有意义的对象。如果有,我会去的选项4

+0

感谢Gamb。这是更多的代码和工作,但我认为它会为更清洁,更可测试的应用程序。如果我能接受你和@ Bedwyr的,我会 - 随机选择一个。 –

+0

@SeanConnolly不用担心,很乐意帮忙:) – Gamb

3

有三种方式:

使用预先抓取负载为您的属性:可能是一个问题,如果你有一个大的数据表。

使用过滤器叫做OpenSessionInView:此过滤器将保持该会话开到你的网页的满负荷。如果有任何hibernate对象在这个加载中被请求,那么会话将被打开并且将避免延迟加载异常。

用户VOs(Valueble对象):在您的应用程序中,将有2种对象。在持久层和业务层之间传递的对象,以及为您查看图层的对象。例如,UserVO和UserModel。 vo将用于在视图和业务层之间传输信息。在您的业务实施中,您将使用vo来填充模型对象以将其发送给持久层。使用这种模式,你不会有更多的延迟加载异常,因为所有需要的信息将在必要时填充到你的vo对象中。

一些参考:
OpenSessionInView
Eager Fetching Load
Hibernate Performance tips