我有一个使用QueryDSL JPAQuery的应用程序。在这里:
JPAQuery<MyWrapper> searchQuery
= queryFactory.select(Projections.constructor(MyWrapper.class,
deviceGroup.id,
deviceGroup.name,
deviceGroup.orientation,
deviceGroup.location,
deviceGroup.customer,
workgroup.account,
Expressions.as(queryFactory.select(device.count())
.from(device)
.where(device.group.id.eq(deviceGroup.id)), "displaysQty"),
Expressions.as(queryFactory.select(device.count())
.from(device)
.where(device.group.id.eq(deviceGroup.id),
device.status.eq(DeviceStatus.HEALTHY)), "healthyQty"),
Expressions.as(queryFactory.select(device.count())
.from(device)
.where(device.group.id.eq(deviceGroup.id),
device.status.eq(DeviceStatus.NO_SYNC)), "noSyncQty"),
Expressions.as(queryFactory.select(device.count())
.from(device)
.where(device.group.id.eq(deviceGroup.id),
device.status.eq(DeviceStatus.NEED_SERVICE)), "needServiceQty"),
Expressions.as(queryFactory.select(device.count())
.from(device)
.where(device.group.id.eq(deviceGroup.id),
device.status.eq(DeviceStatus.OUT_OF_SERVICE)), "outOfServiceQty")))
.from(deviceGroup)
.leftJoin(deviceGroup.customer, workgroup).fetchJoin()
.leftJoin(workgroup.account, account).fetchJoin()
.where(predicate)
.orderBy(sortingParams.toArray(new OrderSpecifier[0]));
MyWrapper 如下:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyWrapper{
private Long id;
private String name;
private DsmsOrientationType orientation;
private String location;
private WorkgroupEntityJpa customer;
private AccountEntityJpa account;
private long displaysQty;
private long healthyQty;
private long noSyncQty;
private long needServiceQty;
private long outOfServiceQty;
}
而且我遇到了一个例外,即查询指定了连接获取,但是选择列表中没有该获取的关联的所有者。
我已经尝试使用 deviceGroup.customer.account 而不是 workgroup.account ,结果是相同的。
UPD 这是 JPAQuery.toString():
select deviceGroupEntityJpa.id,
deviceGroupEntityJpa.name,
deviceGroupEntityJpa.orientation,
deviceGroupEntityJpa.location,
deviceGroupEntityJpa.customer,
workgroupEntityJpa.account,
(select count(deviceEntityJpa)
from DeviceEntityJpa deviceEntityJpa
where deviceEntityJpa.group.id = deviceGroupEntityJpa.id) as displaysQty,
(select count(deviceEntityJpa)
from DeviceEntityJpa deviceEntityJpa
where deviceEntityJpa.group.id = deviceGroupEntityJpa.id and deviceEntityJpa.status = ?1) as healthyQty,
(select count(deviceEntityJpa)
from DeviceEntityJpa deviceEntityJpa
where deviceEntityJpa.group.id = deviceGroupEntityJpa.id and deviceEntityJpa.status = ?2) as noSyncQty,
(select count(deviceEntityJpa)
from DeviceEntityJpa deviceEntityJpa
where deviceEntityJpa.group.id = deviceGroupEntityJpa.id and deviceEntityJpa.status = ?3) as needServiceQty,
(select count(deviceEntityJpa)
from DeviceEntityJpa deviceEntityJpa
where deviceEntityJpa.group.id = deviceGroupEntityJpa.id and deviceEntityJpa.status = ?4) as outOfServiceQty
from DeviceGroupEntityJpa deviceGroupEntityJpa
left join fetch deviceGroupEntityJpa.customer as workgroupEntityJpa
left join fetch workgroupEntityJpa.account as accountEntityJpa
答案 0 :(得分:0)
根据错误消息,此处不需要联接获取,因为这是一种性能提示,可强制加载紧急集合。
因此,请使用常规联接而不是联接提取。
答案 1 :(得分:0)
由于具有DTO投影,因此FETCH指令在这里没有意义。 fetch指令告诉Hibernate将关联包含在SELECT子句中,但是您不希望这样做,因为DTO投影不需要FETCH指令。
类似的东西:
SELECT new EmployeeDTO(e.obj1,e.obj2,e.obj3,e.startDate,e.endDate)
FROM Employee e
left outer join fetch e.obj1
left outer join fetch e.obj2
left outer join fetch e.obj3
由于上述原因无效。
解决方案
只需删除fetch关键字即可。