在DTO内返回另一个实体或DTO

时间:2018-03-30 13:19:49

标签: java hibernate hql dto

所以基本上我正在编写一个使用DTO的API,但是我无法在DTO中返回另一个实体。

这是我的DTO:

public class DirectoryDTO {

  String personFirstName;
  String personLastName;
  Hrper hrper;

  public DirectoryDTO(String personFirstName, String personLastName, Hrper hrper) {
    this.personFirstName = personFirstName;
    this.personLastName = personLastName;
    this.hrper = hrper;
   }
  // getters and setters
}

我使用查询的服务:

public List<DirectoryDTO> getCustomDirectoryEntries(String department) {

  List<DirectoryDTO> directoryDTOS = em.createQuery(
        "select new dto.DirectoryDTO(" +
                "p.firstName, " +
                "p.lastName, " +
                "p.hrper " +
                ")  " +
                "  from Person p " 
                , DirectoryDTO.class)
        .getResultList();

  return directoryDTOS;
}

所以基本上这会返回一个directoryDTO列表,其中所有信息都填写了EXCEPT,用于加入Person的Hrper实体:

返回的数据:

{
    "personFirstName": "John",
    "personLastName": "Doe",
    "hrper": null
}, ....

其他一些事情......

1)当我在查询中取出DTO部分并将结果写入列表时,我在Hrper中获取数据意味着我的连接不正确。

2)我也尝试用DirectoryDTO中创建的HrperDTO HrperDto替换Hrper Hrper,但后来我的查询不能运行,因为它正在寻找DTO而不仅仅是实体

2 个答案:

答案 0 :(得分:0)

我正是为此用例创建了Blaze-Persistence Entity Views。您实际上将JPA实体的DTO定义为接口,并将其应用于查询。它支持映射嵌套的DTO,集合等,本质上是您期望的所有内容,此外,它还将提高查询性能,因为它将生成查询,仅提取您实际为DTO所需的数据。

您的实体视图示例看起来像这样

@EntityView(Directory.class)
interface DirectoryDTO {
  @Mapping("firstName")
  String getPersonFirstName();
  @Mapping("lastName")
  String getPersonLastName();
  HrperDto getHrper();
}

@EntityView(Hrper.class)
interface HrperDTO {
  // attributes of Hrper that you need
}

查询看起来像这样

public List<DirectoryDTO> getCustomDirectoryEntries(String department) {
  List<DirectoryDTO> directoryDTOS = entityViewManager.applySetting(
    EntityViewSetting.create(DirectoryDTO.class),
    criteriaBuilderFactory.create(em, Person.class)
  ).getResultList();

  return directoryDTOS;
}

答案 1 :(得分:0)

好吧,您没有提供实体,因此我无法对其进行测试,但这是一件快速的尝试,因此希望我不会浪费太多时间(如果它不起作用)。尝试使用JOIN FETCH语法明确告诉JPA立即加载相关实体。尝试将from Person p替换为from Person p join fetch p.hrpr h

由于SELECT NEW除非您告知,否则IIRC不会检索对象的完整图形,因此您甚至可能不需要fetch关键字-这可能起作用:{{1} }。