Как правильно получить результаты запроса JPA JOIN? - PullRequest
0 голосов
/ 29 сентября 2019

У меня есть две сущности JPA:

@Entity
public class ClientEntity {
   ...
   @OneToMany(fetch = LAZY)
   private List<OrderEntity> orders;
}

@Entity
public class OrderEntity {
   ...
   @ManyToOne
   private ClientEntity client;
}

Я делаю LEFT OUTER JOIN, используя API спецификации JPA:

public static Specification<ClientEntity> allClientsOrders() {
    return (root, query, cb) -> {
        Join<ClientEntity, TestOrderEntity> join = root.join("orders", JoinType.LEFT);
        return cb.and();
    };
}

Теперь мне нужно получить стандартные результаты JOIN: еслиУ клиента есть 3 заказа в БД, я хочу, чтобы он возвращался 3 раза с другим заказом каждый раз.Однако он возвращает мне клиента 3 раза, но каждый раз, когда у клиента есть все 3 заказа.

Как я вижу в журналах, Java правильно отправляет первый запрос SQL, но затем отправляет другие запросы, чтобы заполнить клиентазаказы как обычно.

Как я могу предотвратить это и получить результаты как один клиент - одна пара заказов?

1 Ответ

0 голосов
/ 29 сентября 2019

Невозможно запретить Клиенту загружать только некоторую часть отношения.

Но операция объединения не требуется для целей, которые вы описали.Вместо этого ищите заказы.Вы получите 3 заказа.Каждый ордер имеет отношение к клиенту, поэтому вы получите то, что вам нужно: 3 ордера, каждый из которых объединен с клиентом.

Если по какой-то причине вы хотите, чтобы ваш запрос возвращал комбинации этих двух типов, рассмотритеследующий подход: определите новый bean / DTO, который будет представлять проекцию полей каждой комбинации ваших двух объектов.Затем используйте JPQL следующим образом:

select new mypackage.MyJoinDto (
    c.id,
    c.firstName,
    c.lastName,
    ...
    o.productName,
    o.orderDate,
    ...
)
from ClientEntity c left outer join TestOrderEntity o
    on o.clientId = c.id

Этот MyJoinDto не нуждается в каких-либо аннотациях JPA.

...