MVC与延迟加载

纠正我,如果这是一个完全重复,我知道这个主题经常讨论,但无法找到明确的答案。

问题是:

在MVC webapp中处理Hibernate对象的最佳实用解决方案是什么?

细节:

我正在使用Hibernate,并希望尽可能利用延迟加载。
我正在使用MVC风格的webapp。
我讨厌得到延迟加载初始化exception。
我讨厌在事务之间重新连接Hibernate对象。

选项:

  1. 渴望加载一切
    • 解决了延迟初始化问题,但使我的查询更大
  2. 使用一些“在视图中打开会话”的概念
    • 我喜欢它的简单性
    • 对象仍然需要重新连接,并且在AJAXy设置中,经常需要重新连接
    • 会话将针对每个请求打开
  3. 在离开交易之前我需要“触摸”项目
    • 看起来最脆弱……而且单调乏味
  4. 创建不同的,简化的“分离”对象,以便视图永远不会看到真正的Hibernate对象
    • 这些可能比完整的Hibernate对象更简单,因此它不像模型的完全热切负载
    • 我听说这个地方推荐,但似乎更多的责任/代码/工作
  5. 如果我想与Hibernate对象进行交互,请打开一个会话。
    • 这可以很好地包含在Spring Service层中,但有时似乎过多。 例如:我想要hibernateObject.getRelatedObjects()但需要说一些像springService.getRelatedObjects(hibernateObject)东西

我错过了什么吗?
我是否过度思考过?
我有没有想过的事情?

PS:

对于Web框架,我使用的是ZK,但并不真正需要ZK特定的答案。
我也使用Spring而且很酷,只有Spring特定的答案,因为它无处不在。

使用4-ish – 不要在视图中使用开放会话,不要让你的hibernate实体一直冒泡到视图,而是让变换器在hibernate实体和你的域对象或’view beans’之间进行转换,具体取决于你的方式想要工作。

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

有三种方法:

对属性使用eager fetch load:如果你有一个很大的数据表可能会有问题。

使用名为OpenSessionInView的filter:此filter将使会话保持打开状态,直到您的网页完全加载为止。 如果在此加载中请求了任何hibernate对象,则会打开会话并避免延迟加载exception。

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

一些参考:
OpenSessionInView
渴望获取负载
Hibernate性能提示

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

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

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