Ich habe eine Entität, die eine Liste von Elementen enthält, und jetzt möchte ich über Attribute dieser Elemente suchen. Diese Einschränkung sollte "und" verbunden sein. Bitte beachten Sie dieses einfache Beispiel:JPA CriteriaBuilder finde Entität, die Elemente mit bestimmten Attributen in der Sammlung hat
@Entity
public class Parent {
@Column
@Enumerated(EnumType.STRING)
private City city;
@OneToMany(...)
private List<Children> childrens;
}
@Entity
public class Children {
@Column
@Enumerated(EnumType.STRING)
private School school;
@Column
private Integer yearInSchool;
}
Jetzt mag ich Eltern in einer bestimmten Stadt zu finden, läßt „BigCity“ sagt mit Kindern in der Schule „AwesomeSchool“, die in der Klasse/Jahr 6. Ich mag um die Suche bekommen Ergebnis nur über CriteriaBuilder.
Bisher habe ich:
final CriteriaBuilder c = getCriteriaBuilder();
final CriteriaQuery<Parent> query = c.createQuery(Parent.class);
final Root<Parent> r = query.from(Parent.class);
query.select(r)
.where(c.and(c.equal(r.get("city"), City.BigCity)),
c.equal(r.get("childrens").get("school"), School.AwesomeSchool),
c.equal(r.get("childrens").get("yearInSchool"), 6));
Leider gibt es zwei Probleme: - es sieht aus wie ich nicht get("school")
auf der Liste Attribut aufrufen können - dies wird alle Eltern mit Kindern zurückkehren, die entweder in "AwesomeSchool" oder sind 6 Jahre in der Schule.
Können Sie mir bitte helfen? Ich habe darüber nachgedacht, einen Join zu verwenden, aber da ist die gleiche Frage: Wie kann ich den where
Teil des Joins definieren, so dass er beide Attribute (school und yearInSchool) gleichzeitig erfüllen muss. Ich habe ähnliche Artikel über die Abfrage von Objekten gefunden, deren Kinder eine Bedingung erfüllen - aber hier müssen die Kinder zwei Bedingungen gleichzeitig erfüllen.
Update 1 Wenn ich eine Verknüpfung verwenden, um z. Ich die „Schule“ von einem Kind, bekomme so weit über das Prädikat:
Predicate predicate = r.join("childrens").get("school").in(School.AwesomeSchool)
Wie kann ich wieder verwende dieses Objekt für die zweite Filterbedingung zu behaupten verbunden ist auch?
, wie Sie es haben zur Zeit werden Sie zu einem Zeitpunkt eine Bedingung auf das Kind zu erfüllen, so Kind 1 kann eine Bedingung erfüllen, aber Kind 2 eine weitere Bedingung . Sie möchten, dass das gleiche Kind beide Bedingungen erfüllt. Daher müssen Sie einen Join verwenden und das verbundene Objekt in der zweiten und dritten where-Klausel verwenden. Es lohnt sich, es als JPQL zu schreiben, bevor der Criteria-Teil ausgeführt wird. –
Hallo Neil, danke für deinen Kommentar. Ja, du hast mein Problem vollkommen verstanden. Ich habe die Frage mit einem Join für eine Bedingung aktualisiert. Wie kann ich dieses Objekt wiederverwenden, um nach der zweiten Bedingung zu filtern? –