JPA Criteria API - 如何选择"字段不在"

时间:2014-04-28 11:28:24

标签: java jpa criteria-api

我有以下情况。

public class TestExecution {

    private Collection<TestExecutionTag> testExecutionTags;

}


public class TestExecutionTag {


    private Tag tag;

}


public class Tag {

    private String name;

}

我现在要做的是使用标准JPA Criteria API执行以下查询,例如:

Select test executions (TestExecution) which don't have associated any of the tags (Tag) with name field value in provided list.

我会将其描述为

Select testExecution WHERE testExecution.testExecutionTag.tag.name NOT IN (<ArrayList of String values>).

这样的事情可能吗?

编辑:对不起,我没有正确指定,因为我觉得它无关紧要。实际上,整个目标是选择具有特定标签的测试执行,但是从中排除包含其他标签的测试。

1 个答案:

答案 0 :(得分:1)

我终于得到了答案,但非常感谢@Priyesh评论和此链接:"Not in" constraint using JPA criteria

编辑后我意识到目标差异不大(参见编辑后的帖子)。

因此必须使用子查询,请参阅:JPQL, How to NOT select something

对于任何人来说,这里是适用于我的Criteria API查询,但它基本上只是重写上面的JPQL查询。

Predicate wantedToBePresentTags = cb.lower(rTag.<String>get("name")).in(cb.parameter(List.class, "tagList"));

Subquery sq = criteriaQuery.subquery(TestExecution.class);
Root sqRoot = sq.from(TestExecution.class);
Join<TestExecution, Tag> sqTag = sqRoot.joinCollection("testExecutionTags").join("tag");
sq.select(sqRoot.get("id"));
sq.where(cb.lower(sqTag.<String>get("name")).in(cb.parameter(List.class, "excludedTagList")));

Predicate excludedTags = cb.not(rExec.get("id").in(sq));

...
criteriaQuery.where(cb.and(wantedToBePresentTags, excludedTags));

希望这有助于某人! : - )