[英]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.