我想用CriteriaBuilder构造一个查询,并将谓词添加到where指令中,以从可能的ENUM值列表中过滤我的对象字段之一。
尽管有类似的帖子:Filtering data with CriteriaBuilder to compare enum values with literals not working
我没有设法使我的代码正常工作。这是“简化的”对象:
//BUNCH OF ANNOTATIONS
public class Action {
@Column(name = "CONTEXT")
@Enumerated(EnumType.STRING)
private ActionContext context = ActionContext.SALE;
// ...
}
我的枚举是:
public enum ActionContext {
SALE,
ORDER,
OTHER
}
例如,在我的过滤器中,我可以收到类似“ SALE,ORDER”的东西。
所以我创建了一个自定义规范,当我构造它时,我正在这样做:
private List<Predicate> filters = new ArrayList<>();
//...
// filterValue is a String, it can be "SALE,ORDER" for ex.
case CONTEXT_FILTER_NAME:
if (filterValue != null && !filterValue.isEmpty()) {
String[] contextTokens = filterValue.split(",");
CriteriaBuilder.In<String> inClause = cb.in(root.get(CONTEXT_FILTER_NAME));
Arrays.asList(contextTokens).forEach(inClause::value);
filters.add(inClause);
}
break;
后面的部分只是执行查询,它适用于其他过滤器...但是事实是我的实体有一个枚举:当我使用这些过滤器运行测试时(将ex发送“ SALE,ORDER”过滤器),以下错误:
参数值[SALE]与预期类型不匹配[com.mycompany.domain.enums.ActionContext
[我也尝试通过用.or()替换CriteriaBuilder.in并放入已解析标记的集合,但是我遇到相同的错误。
[是的,我确定这不是解析错误,因为当我在此swich / case节中放置断点时,我看到其中正确构造的contextTokens数组具有很好的价值。在“ in”规范中,我可以看到设置了正确的值。
有人知道我在想什么吗?非常感谢
确定,我正在将Enum与String进行比较,但我没有看到这个...因此,在这种情况下,您只需用ActionContext.valueOf(token)
或其他方式转换ActionContext ENUM,就转换root.get(CONTEXT_FILTER_NAME).as(String.class)
。
希望它可以帮助像我这样的人,有时以某种隧道的眼光。