2012-04-02 3 views
4

Ich beobachte, was ich denke, ist ein unerwartetes Verhalten in JPA 2 beim Abrufen eines Listenattributs mit einer Kriterienabfrage.Jpa-Kriterien Abfrage doppelte Werte in abgerufene Liste

Meine Frage lautet wie folgt (ein Auszug davon):

CriteriaBuilder b = em.getCriteriaBuilder(); 
CriteriaQuery<MainObject> c = b.createQuery(MainObject.class); 
Root<MainObject> root = c.from(MainObject.class); 
Join<MainObject, FirstFetch> firstFetch = (Join<MainObject, FirstFetch>) root.fetch(MainObject_.firstFetch); 
firstFetch.fetch(FirstFetch_.secondFetch); //secondFetch is a list 
c.select(root).distinct(true); 

(Also lassen Sie uns sagen, ich bin eine Liste als eine Eigenschaft der Eigenschaft eines Objekts abgerufen werden.)

Die Sache Wenn die Abfrage mehrere Ergebnisse zurückgibt, werden secondFetch-Werte so oft dupliziert, wie Zeilen zurückgegeben werden. Jeder firstFetch sollte nur einen secondFetch haben, aber n stattdessen haben. Die einzige Besonderheit, die ich in diesem Fall sehe, ist alle MainObjects zufällig die gleiche FirstFetch-Instanz zu haben. Also meine Vermutung ist der Join wird gekreuzt, was normal ist, aber dann JPA nicht zuweisen secondFetch Objekt zu jedem der firstFetchs.

Mappings sollte nicht zu speziell sein, Hause genauso geschaffen mehr oder weniger ähnliche

@Entity 
@Table(name="mainobject") 
public class MainObject{ 
    //... 
    private FirstFetch firstFetch; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="mainObject_column") 
    public FirstFetch getFirstFetch() { 
    return firstFetch; 
    } 
} 

und

@Entity 
@Table(name="firstFetch") 
public class FirstFetch{ 
    //... 
    private List<SecondFetch> secondFetch; 

    @OneToMany(mappedBy="secondFetch") 
    public List<SecondFetch> getSecondFetch() { 
     return secondFetch; 
    } 
} 

&

schließlich
@Entity 
@Table(name="secondFetch") 
public class SecondFetch { 
    //.... 
    private FirstFetch firstFetch; //bidirectional 

    @ManyToOne 
    @JoinColumn(name="column") 
    public FirstFetch getFirstFetch() { 
     return firstFetch; 
    } 
} 

ich gesucht habe eine Art von distinct Satz zutreffen um das zu holen, aber es gibt das erwartete Ergebnis dank bekommen keine

Wenn ich

(trotzdem ... ein ‚Patch‘ gewesen wäre) ändern
List<SecondFetch> 

für

Set<SecondFetch> 

ich werde Sätze 'Keys, so fühle ich, dass dies ein Fehlverhalten in JPA-Listen ist.

Ich bin jedoch kein Experte, also könnte ich perfekt einen Fehler in den Zuordnungen oder Abfrage machen. Jede Rückmeldung ist sehr willkommen, um dies zu klären. Danke.

+0

Welchen JPA-Anbieter verwenden Sie? Könnte ein Fehler sein. – James

+0

Ich verwende den Standardanbieter von JBoss 6.1.0, der Hibernate 3.6.6 Final wäre, wenn ich nicht falsch liege. –

+0

Ich habe genau das gleiche Problem. Ich verwende Kriterien API, um die (zweite) Liste wie folgt zu holen: d.fetch (FirstFetch_.secondFetch, JoinType.LEFT); – Jens

Antwort

3

Ich hatte genau das gleiche Problem, obwohl ich JPA-Kriterien-API für die Abfrage verwendet habe.

Nach einigen Recherchen fand ich eine Lösung, die Sie bereits erwähnten (aber nicht verfügbar war, da Sie keine Kriterien API verwenden): Using distinct.

Mit JPA Kriterien es würde wie folgt aussehen:

CriteriaQuery<FirstFetch> query = cb.createQuery(FirstFetch.class); 
Root<AbschnittC> root = query.from(FirstFetch.class); 
root.fetch(FirstFetch_.secondFetch, JoinType.LEFT); 
query.distinct(true); 

Ohne Verwendung query.distinct(true); die resultset wurde in der secondFetch Liste mit der Menge der Objekte multipliziert.

Hibernate hat etwas wie DISTINCT_ROOT_ENTITY, die angemessener klingen als nur eine Abfrage zu unterscheiden. Aber ich habe das nicht weiter untersucht. Ich verwende Hibernate auch als JPA-Provider. Vielleicht die Einstellung query distinct in JPA endet mit dem gleichen Code wie Hibernates DISTINCT_ROOT_ENTITY würde?

+0

danke für das Feedback, ich werde einen Blick auf diese DISTINCT_ROOT_ENTITY werfen und so schnell wie möglich aktualisieren –

+0

Ihr Beispiel nur ein fetch(); Ich denke nicht, dass es dasselbe ist wie oben beschrieben. – rakslice