JPA规范对CriteriaBuilder.or()方法不起作用

问题描述 投票:0回答:1

我想得到的就像-

SELECT * FROM emials WHERE user_id = ?1 AND (`to` like '%?2%' OR `from` LIKE '%?2%' OR subject LIKE '%?2%');

要得到这种,我有以下类似的规范-

public class VendorEmailSpecification {
    public static Specification<VendorEmail> filter(String filterText) {
        return new Specification<VendorEmail>() {
            @Override
            public Predicate toPredicate(Root<VendorEmail> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();

                if(!StringUtils.isEmpty(filterText)) {
                    /***
                    * this block donot have any effects
                    **/
                    predicate = criteriaBuilder.or(
                            criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("to"),"%"+ filterText +"%")),
                            criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("from"),"%"+ filterText +"%")),
                            criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("subject"),"%"+ filterText +"%")),
                            criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("message"),"%"+ filterText +"%"))
                   );
                }
                // there is an relation of ManyToOne with user and AuthUserThread.getContext() gives an object of User entity.
                // this working perfectly
                predicate = criteriaBuilder.and(predicate,criteriaBuilder.equal(root.get("user"), AuthUserThread.getContext()));


                return predicate;
            }
        };
    }
}

那里有什么错误,我该如何解决?

java spring-boot jpa specifications
1个回答
0
投票

当调用filterText方法时,似乎toPredicate()参数已超出范围。

如果将成员添加到由Specification<VendorEmail>方法返回的匿名filter()实例中,则将filterText参数的值分配给该成员,并更新其余代码以引用新成员,如下所示,应该可以解决问题:

public class VendorEmailSpecification {
    public static Specification<VendorEmail> filter(String filterText) {
        return new Specification<VendorEmail>() {
            private String filterValue = filterText;

            @Override
            public Predicate toPredicate(Root<VendorEmail> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();
                if(!StringUtils.isEmpty(this.filterValue)) {
                    /***
                    * this block donot have any effects
                    **/
                    predicate = criteriaBuilder.or(
                        criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("to"),"%"+ this.filterValue +"%")),
                        criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("from"),"%"+ this.filterValue +"%")),
                        criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("subject"),"%"+ this.filterValue +"%")),
                        criteriaBuilder.or(predicate, criteriaBuilder.like(root.get("message"),"%"+ this.filterValue +"%"))
               );
            }
            // there is an relation of ManyToOne with user and AuthUserThread.getContext() gives an object of User entity.
            // this working perfectly
            predicate = criteriaBuilder.and(predicate,criteriaBuilder.equal(root.get("user"), AuthUserThread.getContext()));
            return predicate;
            }
        };
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.