如何在 join fetch QueryDSL JPAQuery 中选择



我有一个带有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

根据错误消息,此处不需要联接提取,因为这是一个性能提示,会强制预先加载集合。

因此,请使用常规联接而不是联接提取。

由于您有 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 关键字即可。

最新更新