繁体   English   中英

JPA 规范对 CriteriaBuilder.or() 方法没有影响

[英]JPA specification has no effect with CriteriaBuilder.or() method

我想要得到的是 -

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

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

toPredicate()方法时,看起来filterText参数将超出 scope 。

如果将成员添加到filter()方法返回的匿名Specification<VendorEmail>实例,将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;
            }
        };
    }
}

我用另一种方式解决了这个问题-

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();
                predicate = criteriaBuilder.equal(root.get("user"), AuthUserThread.getContext());
                if(!StringUtils.isEmpty(filterText)) {
                    Predicate toPredicate = criteriaBuilder.like(root.get("to"), "%"+filterText+"%");
                    Predicate fromPredicate = criteriaBuilder.like(root.get("from"), "%"+filterText+"%");
                    Predicate subjectPredicate = criteriaBuilder.like(root.get("subject"), "%"+filterText+"%");
                    Predicate messagePredicate = criteriaBuilder.like(root.get("message"), "%"+filterText+"%");
                    Predicate orPredicate = criteriaBuilder.or(toPredicate, fromPredicate, subjectPredicate, messagePredicate);
                    predicate = criteriaBuilder.and(predicate, orPredicate);
                    return predicate;
                }

                predicate = criteriaBuilder.and(predicate);
                return predicate;
            }
        };
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM