MVC与延迟加载

时间:2013-01-16 14:04:46

标签: java spring hibernate transactions zk

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

问题:

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

详细信息:

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

选项:

  1. 急切加载一切
    • 解决了延迟初始化问题,但使我的查询更大
  2. 使用一些“在视图中打开会话”的概念
    • 我喜欢它的简洁性
    • 对象仍然需要重新附加,并且在AJAXy设置中,经常需要
    • 为每个请求打开一个会话
  3. 在离开交易之前,我需要
  4. '触摸'项目
    • 充其量只是脆弱而且乏味
  5. 创建不同的,简化的“分离”对象,以便视图永远不会看到真正的Hibernate对象
    • 这些可能比完整的Hibernate对象更简单,因此它不像模型的完全热切负载
    • 我听说过这个地方的建议,但似乎更多的责任/代码/工作
  6. 当我想要与Hibernate对象进行交互时,打开一个会话。
    • 这可以很好地包装在Spring Service层中,但有时似乎过多。例如:我想hibernateObject.getRelatedObjects(),但需要说springService.getRelatedObjects(hibernateObject)
    • 之类的内容
  7. 我错过了什么吗? 我是否过度思考过? 我有没有想过的事情?

    PS:

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

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

有三种方法:

对您的属性使用预先获取加载: 如果您拥有大数据表,则可能会出现问题。

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

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

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

答案 2 :(得分:1)

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

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

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