Проект SetPath в выражении конструктора - PullRequest
0 голосов
/ 11 февраля 2019

Я хочу использовать выражение ConstructorExpression для извлечения некоторых данных в DTO.Я не создаю явно весь запрос, вместо этого у меня есть собственный репозиторий Spring Data JPA, который принимает некоторый предикат и выражение конструктора, например так:

 querydsl.applyPagination(pageable, createQuery(predicate).select(factoryExpression));

У меня проблемы со свойствами коллекции.Простое выполнение QMyType.myType.stringProperty работает нормально, но когда у меня есть, например, Набор сущностей, и я просто хотел бы получить список одного из их свойств.Пример: у меня есть заказ, в котором есть набор заказанных товаров.В моем DTO я просто хочу свой заказ со списком имен элементов:

@Entity
public class Order {
    @Id private Long id;
    private String desc;
    @OneToMany(mappedBy = "order") private Set<Item> items;
}

@Entity
public class Item {
    @Id private Long id;
    private String name;
    @ManyToOne private Order order;
}

public class OrderDto {
    private String desc;
    private List<String> itemNames;
}

ConstructorExpression<OrderDto> dtoConstructor = Projections.constructor(OrderDto.class,
    QOrder.desc,
    Projections.list(QOrder.items.any().name));

Для этого последнего элемента я пробовал пару вещей, но я не знаю, как сказать QueryDSL fetchсвязанные дочерние объекты, извлеките свойство и создайте список.Я думаю, это было бы похоже на:

SELECT o.id, i.name
FROM order o
JOIN item i ON o.id = i.order_id

РЕДАКТИРОВАТЬ: Фон таков: хранилище данных Spring с QueryDslPredicateExecutor удобно получать фильтры через REST и применять их для динамического запроса.Я хотел сделать этот шаг дальше, добавив ConstructorExpression, чтобы автоматически генерировать DTO.Это прекрасно работает, если вы не хотите получать (значения из) коллекции.Я провел некоторые исследования, и это работает почти так, как и предполагалось:

JPAQueryFactory queryFactory = new JPAQueryFactory(eM);
QOrder ord = QOrder.order;
QItem item = new QItem("item");
Map<Long, OrderDto> res = queryFactory
    .from(ord)
    .leftJoin(ord.items, item)
    .transform(
        groupBy(ord.id).as(
            Projections.constructor(OrderDto.class, 
                ord.desc, list(item.name))));

Я говорю почти, потому что это Map<Long, OrderDto> вместо List<OrderDto> (на самом деле, это должно быть Page<OrderDto>, ноточка - это идентификатор группы по.)

Более того, я не знаю, должен ли я изменить свой репозиторий, чтобы он брал все необходимые компоненты запроса (части соединения и преобразования).Полагаю, мне нужно было бы пройти весь запрос, но тогда мне все равно нужно применить нумерацию страниц, создать запрос подсчета и т. Д.

Есть ли что-то, что я здесь упускаю?

...