所以基本上我正在编写一个使用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而不仅仅是实体
答案 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} }。