Ich habe eine Methode, die die Methode „toPredicate“ überschreibt:Wie verwendet man javax.persistence.criteria.Predicate mit komplexen Typen?
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
ich die Prädikate zu bauen. Es ist einfach, mit einfachen Typen, zum Beispiel:
@Entity
@Table
public class Person {
@Column
private String name;
@Column
private String surname;
}
Mit dieser einfachen Klasse kann ich tun:
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(surname)) {
predicates.add(cb.equal(root.get("surname"), surname));
}
if (StringUtils.isNotBlank(name)) {
predicates.add(cb.equal(root.get("name"), name));
}
Aber wenn das Attribut ein komplexer Typ ist, wie kann ich das einfache Attribut finden enthielt in der komplexe Typ?
Dies ist eine mögliche Situation:
@Entity
@Table
public class Person {
@Column
private String name;
@Column
private String surname;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Document> documents;
}
@Entity
@Table
public class Document {
@Column
private String type;
@Column
private String code;
}
Was muss ich tun, wenn ich ein Prädikat mit dem komplexen Attribut „Dokumente“ machen?
Ich habe versucht:
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(type)) {
predicates.add(cb.equal(root.get("documents").get("type"), type));
}
Aber ich habe diese Ausnahme:
java.lang.IllegalStateException: Illegal attempt to dereference path source [null.documents] of basic type
at org.hibernate.jpa.criteria.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:98)
at org.hibernate.jpa.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:191)
Meine Aufgabe ist es, jede Person mit einer bestimmten Art von Dokument zu finden. Wie kann ich es tun?
Danke.
Ok, danke für die vorschlagen. Es scheint zu funktionieren, aber es gibt immer noch ein Problem. Wenn ich Folgendes mache: Prädikate.add (cb.equal (root.join ("Dokumente"). Get ("Typ"), Typ)); Es gibt alle Dokumente mit einem bestimmten Typ zurück, sodass ich doppelte Ergebnisse für die Klasse Person erhalten kann. Ein Beispiel: "Jack" Person hat drei Dokumente, von denen 2 Typ = "Papier" haben. Mit dieser Implementierung habe ich 2 Datensätze vom Typ "Person" (beide sind "Jack") –
@AlessandroC werfen Sie einen Blick auf meine Bearbeitung –
cq.distinct (true); scheint genug zu sein, cq.select (root) gib mir einen Kompilierungsfehler. Vielen Dank für Ihre Hilfe! –