Criteria API: Abrufen einer Liste zurückgibt wiederholt Hauptsache

Habe ich die folgenden Entitäten; Ticket enthält einen Satz von 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;
}

Ich bin be-Tickets und abrufen der Attribute. Alle 0,1 Attribute stellen kein problem dar. Für Arbeitsaufträge, die ich verwendet, diese Antwort zu erhalten, den folgenden code.

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();

Das Ergebnis ist, dass in einer Abfrage zurückgeben soll mir 1 Ticket mit 5 Arbeitsaufträge, ich bin das abrufen der gleichen Ticket 5 mal.

Wenn ich nur die Arbeitsaufträge ein eifriger Abrufen und löschen Sie die fetch-code, es funktioniert wie es sollte.

Kann mir jemand helfen? Vielen Dank im Voraus.

UPDATE:

Einer Erklärung, warum ich nicht einfach glücklich mit JB Nizet Antwort (auch wenn es am Ende funktioniert).

Wenn ich nur die Beziehung eifrig, JPA prüft genau die gleichen Daten, wenn ich es faul, und fügen Sie die fetch-Klausel, um die Kriterien /JPQL. Die Beziehungen zwischen den verschiedenen Elementen ist auch klar, wie definiere ich das ListAttribute für die Kriterien der Abfrage.

Gibt es einige vernünftige explanaition aus dem Grund, dass der PPV nicht wieder die gleichen Daten in beiden Fällen?

UPDATE FÜR BOUNTY: Während JB Nizet Antwort hat und das Problem lösen, ich finde es trotzdem sinnlos, dass, da zwei Operationen mit der gleichen Bedeutung ("Bekommen Ticket und holt alle WorkOrder innen ticket.workOrders"), das tun Sie, indem Sie ein eager loading braucht keine weiteren änderungen, während die Angabe einer fetch-Anweisung erfordert ein DISTINCT Befehl

  • Wenn Sie einen Blick auf Linke Verknüpfung, es ist die Art, wie es funktioniert. Warum brauchen Sie, um Ergebnisse zu Holen, die von leftjoin?
  • Von den drei verfügbaren Optionen in der Kriterien-API, es ist sinnvoller. Wir sprechen über den PPV hier, so dass ich erwartet, dass die API zu organisieren, die SQL-Entitäten in einem mehr richtige Weg.
  • Siehe meine bearbeitete Antwort.
InformationsquelleAutor SJuan76 | 2012-06-14
Schreibe einen Kommentar