Criteria API: выборка списка повторяет основной объект
У меня есть следующие сущности; Билет содержит набор 0, N WorkOrder:
@Entity
public class Ticket {
...
@OneToMany(mappedBy="ticket", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<WorkOrder> workOrders = null;
...
}
@Entity
public class WorkOrder {
...
@ManyToOne
@JoinColumn(nullable = false)
private Ticket ticket;
}
Я загружаю билеты и выбираю атрибуты. Все атрибуты 0,1 не представляют проблемы. Для заказа работ я использовалэтот ответ чтобы получить следующий код.
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Ticket> criteriaQuery = criteriaBuilder
.createQuery(Ticket.class);
Root<Ticket> rootTicket = criteriaQuery.from(Ticket.class);
ListAttribute<? super Ticket, WorkOrder> workOrders =
rootTicket.getModel().getList("workOrders", WorkOrder.class);
rootTicket.fetch(workOrders, JoinType.LEFT);
// WHERE logic
...
criteriaQuery.select(rootTicket);
TypedQuery<Ticket> query = this.entityManager.createQuery(criteriaQuery);
return query.getResultList();
В результате в запросе, который должен вернуть мне 1 билет с 5 заказами, я получаю один и тот же билет 5 раз.
Если я просто сделаю workOrders Eager Fetch и удаляю код выборки, он работает как надо.
Может кто-нибудь мне помочь? Заранее спасибо.
ОБНОВИТЬ:
Одно объяснение того, почему я не просто доволен ответом Дж. Б. Низета (даже если в конце это сработает).
Когда я просто стремлюсь к отношениям, JPA проверяет те же самые данные, что и когда я делаю их ленивыми и добавляю предложение fetch в Criteria / JPQL. Отношения между различными элементами также ясны, так как я определяюListAttribute
для запроса критериев.
Есть какое-то разумное объяснение, почему JPA не возвращает одинаковые данные в обоих случаях?
ОБНОВЛЕНИЕ ДЛЯ BOUNTY. Хотя ответ JB Nizet действительно решил проблему, я все же считаю бессмысленным, что, учитывая две операции с одинаковым значением (& quot; ПолучитьTicket
и получить всеWorkOrder
внутриticket.workOrders
& quot;), выполнение их энергичной загрузкой не требует дальнейших изменений, в то время как указание выборки требуетDISTINCT
команда