【问题标题】:JPA Criteria api using IN expression with joinJPA Criteria api 使用带有连接的 IN 表达式
【发布时间】:2015-04-04 21:39:17
【问题描述】:

我的实体Request 具有@ManyToMany Set<Region> regions,而Region 实体具有region 类型的枚举类型字段RegionEnum 和区域常量。 我需要创建标准来获取请求,其区域在 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();

我有一个java.lang.IllegalArgumentException: PREDICATE_PASSED_TO_EVALUATION (There is no English translation for this message.)

枚举:

public enum RegionEnum {
CENTRAL("Центральный"),
SOUTH("Южный"),
NWEST("Северо-Западный"),
FEAST("Дальневосточный"),
SIB("Сибирский"),
URFO("Уральский"),
VOLGA("Волжский"),
NCAU("Северо-Кавказский");


private final String value;

private Region(String value) {
    this.value=value;
}

public String value() {
    return this.value;
}

}

我的标准是否正确,枚举有问题吗?还是标准不好?

【问题讨论】:

  • 在您的第一个代码片段中,您没有显示“regs”变量是什么。
  • 我已添加 regs 来提问;我还尝试创建谓词数组 cb.equal(from.join("regions").get("region"),r) ;其中 r 来自 for(RegionEnum r:regs) ,但我有一个 ClassCastException 表明它无法将 String 转换为 RegionEnum 并且我认为问题可能在 enum 并且它正在比较或其他方面,是否有显示 IN 表达式实现的链接?
  • 来自上一条评论:ClassCastException 显示在for(RegionEnum r:regs) 线上,我不明白为什么是字符串? regs 列表中有 Region
  • 您正在使用 from.join("regions").get("region")(...) 加入,但您的区域枚举没有名为 region 的属性。我目前无法验证这一点,但您能否尝试使用 'join("regions").in(regs)' 并告诉我会发生什么?
  • regions 字段是Set&lt;Region&gt;,其中Region 不是枚举,而是具有枚举字段region 的实体类;它可能很复杂,我稍后会改变它;我解决了这个问题 - 从 jsf selectManyCheckbox 中,选定的项目被写入 List 作为字符串,然后它们在标准中无法转换为 RegionEnum 类型。

标签: jpa join criteria-api


【解决方案1】:

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

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

CriteriaBuilder cb;
List<String> values;
Root<Entity> r; // where Entity has String name attribute

现在我们可以使用 EclipseLink 2.6.2 库以这种方式工作创建一个 Predicate 实例:

Predicate good = r.get("name").in(values);

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

Predicate wrong = cb.isTrue(r.get("name").in(values));

即使表达式具有正确的语法,也会在您收到它时引发上述异常 PREDICATE_PASSED_TO_EVALUATION

我认为是因为 Expression 是 Predicate 类的祖先,但这只是一个想法。至少异常消息是这样说的。

所以只需删除 cb.isTrue() 包装,它可能对你有用,因为它对我有用。

【讨论】:

    猜你喜欢
    • 2012-05-30
    • 2013-09-08
    • 2013-08-16
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2012-03-08
    相关资源
    最近更新 更多