Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 在ejb3中使用数据传输对象被认为是最佳实践吗_Hibernate_Design Patterns_Jakarta Ee_Ejb 3.0 - Fatal编程技术网

Hibernate 在ejb3中使用数据传输对象被认为是最佳实践吗

Hibernate 在ejb3中使用数据传输对象被认为是最佳实践吗,hibernate,design-patterns,jakarta-ee,ejb-3.0,Hibernate,Design Patterns,Jakarta Ee,Ejb 3.0,虽然显然不是所有的场景都能被一个单一的设计所覆盖,但是现在是否普遍认为ORM类应该在表示层和业务层(本地或远程)之间来回传递,以取代对数据传输对象的需求?就我所见,使用ORM类会带来不必要的急于加载、上下文管理问题和紧密耦合等问题,但也会节省大量时间并保持简单。现在是否有一种标准方法(在大多数情况下)普遍倾向于一种方法而不是另一种方法?这是一个非常有趣的问题,我在过去两年中一直在研究和试验这个问题 我认为这里真的没有对错的答案。我不认为你可以简单地说我想要一个而不是另一个,因为根据你的客户是什么

虽然显然不是所有的场景都能被一个单一的设计所覆盖,但是现在是否普遍认为ORM类应该在表示层和业务层(本地或远程)之间来回传递,以取代对数据传输对象的需求?就我所见,使用ORM类会带来不必要的急于加载、上下文管理问题和紧密耦合等问题,但也会节省大量时间并保持简单。现在是否有一种标准方法(在大多数情况下)普遍倾向于一种方法而不是另一种方法?

这是一个非常有趣的问题,我在过去两年中一直在研究和试验这个问题

我认为这里真的没有对错的答案。我不认为你可以简单地说我想要一个而不是另一个,因为根据你的客户是什么(网页、ws、机器和/或本地、远程),通常你可能想要一个混合的

这里需要记住的重要一点是,每个产品的优缺点是什么,并根据您的需求应用这些产品

例如:

  • 如果您使用的是SEAM,那么您可能希望避免采用分层结构,因为您可以访问扩展的持久性上下文。没有这种支持的其他web技术倾向于更好地使用预先准备好状态的DTO
  • 如果您正在发送远程消息,那么导入的任务是保持消息的轻薄,DTO通常比rich domain对象在这里工作得更好。在这里,您可以透明地抑制任何ORM问题/行为
  • DTO模式的好处是保护您的客户端不受域更改的影响。如果您的应用程序是一个web服务,那么这一点尤其重要,因为有一个定义合同的域(实体)对象可能会让您在某个点上失去联系

通过将系统包装在层中并小心地公开和保护它们,您可以为许多不同类型的客户机生成各种API

我认为DTOs的存在与JPA/Hibernate缺陷有关。如果您总是能够透明地进行惰性初始化,那么您将永远不会使用它们。因此,使用DTO是一个合同,我的域/工作区总是丢失(到处重复)。
总之,你可以使用它们,但你必须讨厌它们:)

紧密耦合?请解释一下

对我来说,DTO是一种反模式。EJB3允许我们省略使用它们。在将实体发送到客户端之前,您可以强制执行延迟初始化


当然,如果您只需要30个字段中的两个就可以发送给客户机。但是,如果在我当前的项目中,所有的拷贝都是完整的,那么试着去掉那个DTO。我看不出有任何理由使用它们。按照客户机的要求,向客户机发送业务对象。为什么要使用包装器?

我同意最后一位“演讲者”的观点,在ejb3中为什么要使用包装器??我们在没有DTO的情况下构建了一个相当复杂的系统,但使用了实体(JPA),它可以工作。很明显…

如果GUI控制器将对象属性发送到表单而不是实体对象,那么只处理实体就可以了。另一方面,如果使用了实体,并且这些实体具有多对一关系,那么如果实体管理器不急于获取这些实体,那么应该会看到一些令人讨厌的异常

例如,在尝试填充SpringMVC的标记或其他GUI组件的类似构造时,可以观察到这种情况


此外,DTO是放置额外注释(如验证注释或JAXB等)的非常好的地方

我反对在表示层使用实体:

  • 锁定:这最终会在演示文稿和模型之间建立紧密的锁定。在大型项目中,改变也会变得昂贵,甚至是不可能的。现代工具还不太成熟

  • 安全性:使用模型对象,您可以轻松地将各种数据库id信息传输到网页。这显然是一个安全问题。使用
    dto:s
    您可以使用非常简单的会话映射在服务器上隐藏它们

  • 需求差异:GUI视图很少是模型对象的直接列表。更多的时候,它们是更复杂的东西,组合的野兽,伪装。GUI的需求倾向于潜入到您的模型中,使其变得模糊

  • 速度:对于实体,每次读/写时都会处理每个字段。因为您将它们直接传递到表示层,所以您很难尝试优化您的JPA查询—几乎不可能。在未来的项目中,我肯定会回到像myBatis一样的直接JDBC访问。从而消除了ORM

我对
DTO:s
也有异议:

  • 额外的DAO代码
考虑到这一点,我将投票支持在所有项目中使用
dto:s
,同时取消
JPA
。因此,我的堆栈变成如下所示:

  • 数据库访问的myBatis
  • POJO作为DTO:s
  • 我的DAO服务的无状态EJB
  • 用于GUI后端的StatefulEJB
  • JSF用于演示