【发布时间】:2015-07-19 20:52:15
【问题描述】:
有很多文章指出 JPA/hibernate 不需要使用 DTO
使用视图模式中的打开会话或规范的组装阶段来避免未获取数据的问题。Hibernate 将开发人员从编写乏味的数据传输对象 (DTO) 中解放出来... 以上几行来自https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/best-practices.html
另外,在 SO 成员 Bohzo 的 article 中,我读到 DTO 很少需要
即使在 articles 反对暴露实体的声明中,当实体没有任何行为(当它们是 POJO 时)时,也不需要像在贫血领域模型中那样拥有 DTO
假设有一个实体类
class Department{
List<Employee> employees //lazily loaded collection
集合中的每个对象都包含另一个延迟加载的集合
class Employee{
List<Account> accounts
有一个 getDepartment() 方法 被一个restful服务用来提供部门的Json信息。
可能的解决方案是
解决方案 1) 根据休眠文档打开和关闭每个请求的休眠会话(控制器中最上面的方法是事务性的吗?)或者更好地使用 Spring 的 OpenSessionInViewFilter 按照这个 SO post
为什么休眠不能重新打开会话并获取延迟加载的对象而不是抛出异常?有没有办法使用 JPA/休眠进行配置?
解决方案 2) 与 hibernate doc 一样,另一种方法是进行 组装阶段。这到底是什么意思? 将 getDepartment API 分解为 DAO 的不同 API?
解决方案3)使用DTO 即使使用了DTO,持久层如何知道视图是否需要一个完全加载的部门。这个 导致将 API 分解为 getDepartmentOnly() getDepartmentWithEmployees() 和其他人说是获取部门对象的 100% 还是其中的一部分 一个 API 分解为多个实体,映射到多个 DTO
解决方案 4) 在 bohzo 的文章中,分页视图避免延迟加载,并通过查询获取有限的结果
请更正解决方案 2 并解释 hibernate 文档中的意图?
【问题讨论】:
-
见我的answer to this question。是的,EJB3 承诺不再需要 DTO。当我们在 8 年前开始使用 EJB3 时,我们相信这个“口头禅”。在创建了 300 多个实体后,我们意识到这根本行不通,我们需要 DTO。正如我所说,请参阅我对另一个问题的回答。
-
谢谢,但我的问题不是 DTO 是否“总是”需要。这似乎是基于意见的。我的问题是关于它们的正确用法。
-
在安静的 Web 服务中公开模型被认为是不好的做法。更重要的是,API 永远不应该根据视图的需要来设计。所以,如果你的 API 是安静的,你应该使用 DTO。否则,你只是在做 RPC。
-
请理解我的问题不是更好的做法。如何实现文档中关于不使用 DTO 的说明以及如何为本示例构建 DTO
-
使用 DTO 不会让服务变得安静。通过公开实体,发送的实体表示可能与实体本身相同也可能不同。如果 DTO 只是复制实体什么有什么意义吗?在这里您可以找到在 jax-rs 服务中使用的实体adam-bien.com/roller/abien/entry/javaee_7_retired_the_dto 这是来自 jpa2 jcp 和 jsrs 成员的博客。 “总是”并不总是正确的
标签: java spring hibernate jpa design-patterns