Как выбрать в соединении получить QueryDSL JPAQuery? - PullRequest
0 голосов
/ 08 января 2019

У меня есть приложение с 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

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Поскольку у вас есть проекция 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.

0 голосов
/ 08 января 2019

Согласно сообщению об ошибке, выборка соединения здесь не нужна, потому что это подсказка производительности, которая вынуждает загружать коллекцию.

Так что используйте обычное соединение вместо получения соединения.

...