如何对复杂类型使用 javax.persistence.criteria.Predicate?
How to use javax.persistence.criteria.Predicate with complex types?
我有一个覆盖方法 "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;
}
有了这个简单的 class 我可以做到:
@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);
}
我有一个覆盖方法 "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;
}
有了这个简单的 class 我可以做到:
@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);
}