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

标签 java spring-boot jpa specifications

我想要得到的是这样的 -

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

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

最佳答案

看起来像 filterTexttoPredicate() 时,参数将超出范围。方法被调用。

如果您向匿名 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;
            }
        };
    }
}

关于java - JPA 规范对 CriteriaBuilder.or() 方法没有影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61040190/

相关文章:

java - 解码时未找到类

java - 如果不遵循编码约定,在 eclipse 中设置编码约定会引发错误

java - Spring REST 文档 - Junit 测试中的 fieldWithPath

java - 无法加载ApplicationContext。无法创建集成测试

java - Spring Data JPA - 实体名称无效标识符

java - 如何使用Java将RDF代码上传到fuseki服务器?

spring - 使用 Spring + Jersey 的异步 API

java - Hibernate注释一对多

java - JPQL 从 POJO 中的字符串列表中选择不同的字符串

java - 如何为proguard编写规则?