JPA标准api在带有联接的表达式中使用

JPA标准api在带有联接的表达式中使用,jpa,join,criteria-api,Jpa,Join,Criteria Api,我有一个实体请求,它有@manytomy集合区域,并且区域实体有枚举类型的字段区域,带有区域常量。 我需要创建获取请求的标准,其中其区域位于RegionEnum集合中; 我选择: List<RegionEnum> regs=...; // from method parameter CriteriaBuilder cb=em.getCriteriaBuilder(); CriteriaQuery<Request> cq=cb.createQuery(Request.cla

我有一个实体
请求
,它有
@manytomy集合区域
,并且
区域
实体有枚举类型的字段
区域
,带有区域常量。 我需要创建获取请求的标准,其中其区域位于RegionEnum集合中; 我选择:

List<RegionEnum> regs=...; // from method parameter
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery<Request> cq=cb.createQuery(Request.class);

Root<Request> from=cq.from(Request.class);
cq.where(cb.isTrue(from.join("regions").get("region").in(regs)));
return em.createQuery(cq).getResultList();

我的标准正确吗?enum有问题吗?还是标准不好?

我今天遇到了同样的例外,所以我试图解决这个问题

假设已经初始化了以下实例(如您的示例所示):

但是如果我们尝试将谓词包装到cb.isTrue()方法中(正如您所做的那样),该方法需要一个“Expression”参数,如下所示:

Predicate wrong = cb.isTrue(r.get("name").in(values));
所提到的异常谓词\u传递给\u求值将在您收到它时引发,即使表达式具有正确的语法

我认为,因为表达式是谓词类的祖先,但这只是一个想法。至少异常消息是这样说的


所以只需删除cb.isTrue()包装,它可能会像对我一样对您有效。

在您的第一个代码片段中,您没有显示“regs”变量是什么;我还尝试创建谓词数组
cb.equal(from.join(“regions”).get(“region”),r)
;其中r来自(RegionEnum r:regs),但我有一个ClassCastException,它表明它无法将字符串强制转换为RegionEnum,我认为问题可能出在enum中,它正在进行比较或其他事情,表达式实现中是否有显示的链接?来自上一条注释:ClassCastException显示在(RegionEnum r:regs)的
行上
我不明白为什么是字符串?您正在使用from.join(“regions”).get(“Region”)(…)加入的列表regsy中存在区域,但您的区域枚举没有名为Region的属性。我现在无法验证这一点,但您能否尝试在(regs)中使用'join(“regions”).in并让我知道发生了什么情况?
regions
字段是
Set
,其中
Region
不是枚举,而是具有枚举字段
Region
的实体类;它可能很复杂,我稍后会更改它;我修复了这个问题-从jsf selectManyCheckbox,所选项目被写入列表作为字符串,然后它们在条件中无法转换为RegionEnum类型。
CriteriaBuilder cb;
List<String> values;
Root<Entity> r; // where Entity has String name attribute
Predicate good = r.get("name").in(values);
Predicate wrong = cb.isTrue(r.get("name").in(values));