我有一个重写方法"toPredicate"的方法:
@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;
}
如果我想做一个具有复杂属性"documents"的谓词,我该怎么办?
我试过了:
@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)
我的任务是找到每一个拥有确定类型文档的人。我该怎么做?
谢谢。
您可以使用join
:
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
Predicate predicate = null;
if (StringUtils.isNotBlank(type)) {
predicate = cb.equal(root.join("documents").get("type"), type);
cq.where(predicate);
cq.distinct(true);
}