当前位置: 首页 > 知识库问答 >
问题:

正确使用实体和DTO在Restful Web服务中提供Json

曹茂材
2023-03-14

有许多文章指出在JPA/hibernate中不需要使用DTO

使用“在视图中打开会话”模式或严格的程序集阶段来避免未蚀刻数据的问题。Hibernate使开发人员不再编写繁琐的数据传输对象(DTO)。。。以上几行来自https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/best-practices.html

同样在SO成员Bohzo的一篇文章中,我读到DTO很少需要

即使在反对暴露实体的文章中也指出,当实体没有任何行为(当它们是POJO时)时,没有必要像贫血领域模型中那样拥有DTO

假设有一个实体类

class Department{
    List<Employee> employees //lazily loaded collection 

集合中的每个对象都包含另一个懒惰加载的集合

 class Employee{
    List<Account> accounts

restful服务使用getDepartment()方法提供部门的Json信息。

可能的解决办法是

解决方案1)根据Hibernate留档打开和关闭每个请求的Hibernate会话(这是控制器中最重要的方法是事务?)或者更好地使用Spring的OpenSessionInViewFilter作为这个SO帖子

为什么hibernate不能重新打开会话并获取延迟加载的对象,而不是引发异常?有没有办法用JPA/hibernate来配置它?

解决方案2)和hibernate文档一样,另一种方法是有一个组装阶段。这到底是什么意思?将getDepartment API分解为DAO的不同API?

解决方案3)使用DTO,即使使用DTO,持久化层如何知道视图是否需要一个完全加载的部门。这导致将API分解为getDepartmentOnly()getDepartmentWithEmployees()和其他表示是否获取部门对象100%或其一部分的人一个API分解为多个,一个实体映射到多个DTO

解决方案4)在bohzo的文章中,分页视图可以避免懒惰加载,并通过查询获取有限的结果

请更正解决方案2并解释hibernate文档中的意图?

共有1个答案

韩飞翮
2023-03-14

Hibernate文档中的组装阶段意味着:

public Department getDepartmentWithEmployees(Long departmentId) {
   Department result = em.find(Department.class, departmentId);
   Hibernate.initialize(result.getEmployees());
   return result;
}

或:

public Department getDepartmentWithEmployees(Long departmentId) {
   String query = "select d from Department d join fetch d.employees where d.id = :departmentId";
   ...
}

基本上,取回必要的数据以在代码可读性和可维护性与性能(不同API的数量与取回的数据量)之间取得平衡取决于您。

这不是JPA/Hibernate特定的问题;您将需要考虑其他任何持久性框架(或直接JDBC)。

 类似资料:
  • 问题内容: 我们将使用DTO在表示层之间来回发送数据。我们有像这样的图层: facade appService domain 并且我们使用推土机来帮助我们将实体转换为dto。但是我现在有两个问题: 从实体到dto,我们可以使用推土机,但是从dto到实体,我们可以使用推土机吗?如果是,如何? 我应该在哪里创建实体?在外观或DTOAssembler中? 例如,我必须注册一本书。这本书的实体外观如下:

  • 我有一种情况,在一个DTO中有另一个DTO,我必须映射到它对应的实体。 我正在使用mapstruct,我已经有antherEntityMapper已经存在。 如何更改EntityMapper接口,以便我可以将一个另一个EntityDTO映射到另一个Entity? 谢谢

  • 我试图在我的项目中巧妙地使用DTO和实体,但它似乎比它应该的更复杂。我正在构建一个管理库存的后端,我使用NestJs和TypeOrm。 我的客户向我发送了一组数据抛出POST请求,比如: 我的控制器有责任通过使用自定义ValidationPipe检查字段: 我在许多地方读到,在最佳实践中,原始数据应该转换为DTO,当涉及到数据插入时,我应该将DTO转换为类型化实体。 我同意这种方法,但我发现它非常

  • 问题内容: 我正在尝试使用以下方式提供SVG地图: 在Firefox中,这会导致插件提示。如果我重命名地图。svg映射。xml,它可以正确显示图像。我认为这是因为Django的开发服务器(特别是django.views.static.serve)没有为svg提供正确的mime类型。这是问题吗?如果是,是否有补丁? 问题答案: 我目前没有可用的Django来进行测试,但看起来静态服务器使用mimet