Критерии API: выборка списка возвращает повторяющийся основной объект

У меня есть следующие сущности; Заявка содержит набор 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 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

9
задан Community 23 May 2017 в 12:25
поделиться