如何使用复杂类型的javax.persistence.criteria.Predicate?

Ale*_*o C 3 java spring-data spring-data-jpa spring-data-rest javax.persistence

我有一个覆盖方法"toPredicate"的方法:

@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
    List<Predicate> predicates = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

我必须构建谓词.简单类型很容易,例如:

@Entity
@Table
public class Person {

    @Column
    private String name;

    @Column
    private String surname;

}
Run Code Online (Sandbox Code Playgroud)

通过这个简单的课程,我可以做到:

@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));
    }
Run Code Online (Sandbox Code Playgroud)

但是如果属性是复杂类型,我如何找到复杂类型中包含的简单属性?

这是一种潜在的情况:

@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;

}
Run Code Online (Sandbox Code Playgroud)

如果我想用复杂属性"文档"创建谓词,我该怎么办?

我试过了:

@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));
    }
Run Code Online (Sandbox Code Playgroud)

但我有这个例外:

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)
Run Code Online (Sandbox Code Playgroud)

我的任务是找到每个人都有一个确定的文件.我该怎么做?

谢谢.

Raf*_*LDI 6

你可以使用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);

      }
Run Code Online (Sandbox Code Playgroud)