2017-08-22 4 views
0

Ich versuche, QueryDSL mit Spring Data JPA zu verwenden.Mehrere Joins mit QueryDSL

Meine Datenbank hat 3 Tabellen.

1) Eine Account-Tabelle mit Kontoinformationen und speziell eine Kontonummer. 2) Eine PersonRole-Tabelle, die die Rolle einer Person auf einem Konto (wie der Besitzer) und die entsprechende Kontonummer und die ID-Nummer seiner Person hat. 3) Eine Person Tabelle, die Reihen von Personen hat. Ihre ID-Nummer und Vorname, Nachname etc ...

Meine Entitäten wie folgt aussehen:

@Entity 
Account{ 
...Other fields ommited 
**@OneToMany 
@JoinColumn(name = "ACCNT_NUMBER") 
List<PersonRole> personRoles;** 
} 

@Entity 
PersonRole{ 
String role; 
...Other fields ommited 
**@OneToOne 
@JoinColumn(name = "PERSON_ID") 
Person person;** 
} 


@Entity 
Person{...} 

Ich möchte die Konten filtern, die ich von Person Vorname wählen und Nachname und verwenden Sie dann, dass um Vertragseinheiten zu füllen, die verbundene Personen und Personen haben.

Ich gehe davon aus, dass ich Joins erstellen muss, um dies zu tun. Ich habe eine Menge Dinge ausprobiert, aber ich bekomme immer Fehler. Ich habe die entsprechenden QClasses erstellt. Ich weiß, dass der folgende Code falsch ist und es funktioniert nicht, aber vielleicht kannst du sehen, ob ich auf dem richtigen Weg bin und mir vielleicht helfen kann. Jede Hilfe wird sehr geschätzt. Vielen Dank!

QAccount account = QAccount.account; 
    QPersonRole personRoles = QPersonRole.personRole; 
    QPerson person = QPerson.person; 

    JPAQuery<Account> query = new JPAQuery<>(entityManager); 

    List<Account> accountList = query 
      .from(account) 
      .innerJoin(acccount.personRoles, personRoles) 
      .innerJoin(person) 
      .where(person.lastName.eq("John") 
        .and(person.lastName.eq("Doe"))) 
      .fetch(); 
+0

Was meinen Sie mit "Verträge"? Es gibt keinen Code für einen "Vertrag" in der Frage. Warum gibt es auch eine '@ OneToOne'-Verbindung von' PersonRole' zu ​​'Person'? Vermutlich kann eine einzelne "Person" eine Rolle in mehreren "Konten" haben, was mehrere "Personenrollen" -Datensätze bedeuten würde, eine für jedes "Konto", in der die "Person" eine Rolle hat. Daher sollte es eine "@ ManyToOne" -Verbindung von "PersonRole" zu "Person" geben. Wenn nicht, warum speichern Sie nicht einfach den Rollennamen und die Account-Referenz mit der Person selbst? – manish

+0

Sorry, ich meinte Konto nicht Verträge. Ich habe bearbeitet. Es gibt also eine viele zu viele Beziehung zwischen Konten und Personen. Um das zu lösen, verwenden wir eine Join-Tabelle. Obwohl eine Person viele Rollen in einem Vertrag und in verschiedenen Verträgen haben kann, dachte ich mir, indem ich sie zu einem anderen machte, würde sie eine Person für jede Rolle auf dem Vertrag bekommen. Sollte ich das zu Onetomany ändern? – ejgreenwald

Antwort

2

Sie tritt nur benötigen, wenn Sie auf einer zu viele filtern möchten ... JPQL noch genutzt werden können ... und ich würde es vorziehen, eine singuläre auf dem personRole zu verwenden, so:

QAccount account = QAccount.account; 
QPersonRole personRole = QPersonRole.personRole; 

JPAQuery<Account> query = new JPAQuery<>(entityManager); 

List<Account> accountList = query 
      .from(account) 
      .innerJoin(acccount.personRoles, personRole) 
      .where(personRole.person.lastName.eq("John") 
        .and(personRole.person.lastName.eq("Doe"))) 
      .fetch(); 

Beachten Sie, wie die Verbindung zu Person nicht erforderlich ist.

+0

Sie sind ein Held. Danke für all deine Hilfe! Jetzt muss ich nur alles mit BooleanBuilder zusammenbringen und ich möchte auch Spring Data Pagination verwenden. Wenn Sie einen Rat für das Verbinden dieser Punkte haben, würde ich gerne hören :) – ejgreenwald

+0

Sie können nicht die Seitennummerierung der Frühjahrsdaten verwenden, wie Sie Joins in Abfrage dsl tun. Limit und Offset sind deine Freunde. Wenn Sie herausfinden können, wie Sie Federdaten mit einem Join verwenden, lassen Sie es mich wissen –