У меня есть метод, который переопределяет метод «toPredicate»:Как использовать javax.persistence.criteria.Predicate со сложными типами?
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
я должен построить предикаты. Это легко с помощью простых типов, например:
@Entity
@Table
public class Person {
@Column
private String name;
@Column
private String surname;
}
С помощью этого простого класса я могу сделать:
@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));
}
Но если атрибут является сложным типом, как я могу найти простой атрибут, содержащийся в сложный тип?
Это потенциальная ситуация:
@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;
}
Что я должен делать, если я хочу сделать предикат с комплексным атрибутом «документы»?
Я пробовал:
@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));
}
Но у меня есть это исключение:
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)
Моя задача состоит в том, чтобы найти каждый человек с детерминированным видом документа. Как я могу это сделать?
Спасибо.
Хорошо, спасибо за предложить. Кажется, что это работает, но все еще есть проблема. Если я делаю: predicates.add (cb.equal (root.join («документы»). Get («type»), type)); он возвращает все документы с определенным типом, поэтому я могу иметь дубликаты результатов для класса Person. Пример: «Джек» У человека есть три документа, из которых 2 имеют тип = «Бумага». С этой реализацией у меня есть 2 записи типа «Person» (оба являются «Jack») –
@AlessandroC взгляните на мое редактирование –
cq.distinct (true); кажется, достаточно, cq.select (root) дает мне ошибку компиляции. Однако, спасибо за вашу помощь! –