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