Hibernate Web架构:MVC、惰性初始化、数据传输对象、视图中的开放会话,是否有一致的方法?

Hibernate Web架构:MVC、惰性初始化、数据传输对象、视图中的开放会话,是否有一致的方法?,hibernate,spring,architecture,web-architecture,Hibernate,Spring,Architecture,Web Architecture,对于一个典型的web三层应用程序,您在下面的设计中发现了哪些缺陷(以及您理想的架构建议是什么) 我目前的蓝图方法大致是这样的(假设Java、Spring、Hibernate、JSP) 控制器 无状态,可能包装为只读事务(以避免延迟初始化异常),get的实体从持久性存储中仅通过服务,将它们作为模型传递给视图。在它们上执行业务逻辑(BL是否应该仅在服务层中?),如果需要,传递回服务层进行持久化 优点:对于只读事务包装-只有一个连接,同一持久实体没有冗余命中,更好地利用查询缓存,服务层不应“知道”请

对于一个典型的web三层应用程序,您在下面的设计中发现了哪些缺陷(以及您理想的架构建议是什么)

我目前的蓝图方法大致是这样的(假设Java、Spring、Hibernate、JSP)


控制器 无状态,可能包装为只读事务(以避免延迟初始化异常),get的实体从持久性存储中仅通过服务,将它们作为模型传递给视图。在它们上执行业务逻辑(BL是否应该仅在服务层中?),如果需要,传递回服务层进行持久化

优点:对于只读事务包装-只有一个连接,同一持久实体没有冗余命中,更好地利用查询缓存,服务层不应“知道”请求参数,或所需的init图跨度,避免延迟init异常

缺点:只读事务方法可能有风险,控制器不是理想的业务逻辑挂起的地方。。。非常难做JUnits(您的输入是一个请求…)


看法 非事务性(访问非惰性集合/成员将导致惰性初始化异常)

专业人士

  • 视图作者不应仅通过点符号影响应用程序的性能(例如,由于懒散初始化大型集合而导致N+1选择)

  • 此外,在断开连接的客户端(Flex或其他富客户端)中,远程延迟初始化要么不受支持,要么就是不明智

缺点:控制器/服务/DAO必须为视图仔细准备正确的实体图,并且可能会出现过冲(性能)/欠冲(延迟初始化异常)。大量服务器端方法可能会造成混乱,因为实体图可以初始化的排列数有笛卡尔积


模型 按原样使用持久对象(无数据传输对象),状态保存在会话中

优点:无需重写POJO,重用现有实体,会话状态比隐藏字段状态处理更安全

缺点:对断开连接的框架不好,保存陈旧断开连接的对象的风险,锁定问题的风险,覆盖其他人的数据,有时需要乐观锁定


服务 事务性的,不知道请求的作用域,调用DAO层来进行实际的持久性存储访问。这是BL的典型位置,但似乎BL一次又一次地泄漏到控制器端


刀 包含原子持久性存储外观,不知道BL或任何上下文


最后,问题是: 在上述架构中,您将修复什么

你认为(和我一样)这是一种非常普遍的方法(有一些细微的区别,比如在视图中的公开会议等)?还是你第一次看到它,我做了一些非常错误(或正确)的事情

您如何在应用程序中解决它?您是否将实体POJO也用于您的模型和视图?还是将其连接到更简单的UI Bean(都已完全初始化且安全)


这可能是一个主观的问题,但我确信有明确的最佳实践设计模式,可以归纳为一个、两个或三个最大的通用“宗教”.

总的来说,它似乎是一个非常好的体系结构。如果您还没有读过它,我建议您使用Martin Fowlers企业应用程序体系结构模式,它描述了您问题中的每一个主题

这个问题并不清楚您期望性能会有多大。根据我的经验,性能瓶颈很少出现在您认为的地方,而且您越早发现它们,就越容易更改体系结构以匹配它们


您是对的,可测试性是一个主要问题。我已经成功地使用了Martin Fowlers-模式。您还应该看看来自同一站点的Supervision Controller。

您的上述方法听起来不错

但是我认为你应该使用UI Bean。当然这个UI Bean应该是有效的不可变的。一旦它被创建,它的状态(和封装的域对象)就不应该被改变

非常简单的示例:


class UIBean {
  DomainObject o;

  public String getDescription(){
     return trimToSummaryText(o.getDescription());
  }

  private static String trimForSummaryText(){
     ....
  }
}
主要优点:

  • 模板代码会变得更干净、更简洁。你的前端开发人员会为此感到高兴的
  • 您不倾向于向域对象类添加特定于前端的帮助器方法
  • 可以对不同的域对象或视图bean进行分组(UIbean可以有多个字段)

是的,这涉及到更多的java类。但是,只要您的Web应用程序和页面增长,这个抽象层几乎总是很好的。

超级,除非使用SOFEA风格的前端,它基本上摆脱了上述体系结构中的控制器部分

前端完全包含在客户端上,客户端直接调用返回JSON或XML的REST或SOAP服务。这似乎100%解决了转换域对象以显示的问题

也许,有人认为,上面描述的N层体系结构之所以没有干净的解决方案,是因为它完全错了

链接

  • 我当前的项目使用了一种有点过时的N层体系结构和数据传输对象。DTO是不必要的,因为应用程序不是分布式的,而且永远不会。唯一的好处(在我看来不值得)使用DTO的好处在于,它强制为业务方法提供一个干净的接口—视图组件可以随意遍历伪模型上的对象图—不能引发延迟初始化异常

    我在我们的架构中看到的架构难点之一是,业务接口是两个该死的com