JPA Criteria API预测子集合中的多个要求

时间:2016-03-09 13:24:58

标签: java jpa spring-data-jpa criteria-api jpa-2.1

考虑以下情况:

public class Parent {
    private List<Child> childs;
}

public class Child {
    private Target target;
    private Value value;
}

public class Target {
    private Long id;
}

public class Value {
    private Long id;
}

对于每个确定的Target对象,Parent-object将具有具有Value-object的Child对象。

我以HashMap<Long>, List<Long>>格式获取过滤器,其中key是Target-object的id,value是所需Value-object id的列表。 我需要使用JPA Criteria API获得的所有父母都有以下条件:

  • 拥有targetId 1的子级,其值为(1,2,3)
  • 中的valueId
  • AND具有targetId 2的子级,其值为(1,4)
  • 中的valueId

所以我需要排除那些不符合所有要求的结果。有没有办法通过JPA Criteria API实现这一目标。我尝试过以下方法:

List<Predicate> predicates = new ArrayList<>();
...
List<Predicate> subPredicates = new ArrayList<>();
Path<Child> child = root.join(Parent_.child, JoinType.LEFT);
for (Map.Entry<Long, List<Long>> entry : map.entrySet()) {
    Long targetId = entry.getKey();
    List<Long> valueIds = entry.getValue();
    subPredicates.add(cb.and(cb.equal(child.get(Child_.target), targetId), child.get(Child_.value).in(valueIds)));
}
predicates.add(cb.and(subPredicates.toArray(new Predicate[subPredicates.size()])));

但显然它不起作用。这种类结构甚至可能吗?任何人都可以帮我这个吗?

1 个答案:

答案 0 :(得分:0)

我将尝试创建两个联接,两个联接都使用子表,并在每个联接中设置一个条件,因此,如果不满足两个联接之一,则不会出现结果。

例如:

Path<Child> childCondition1 = root.join(Parent_.child, JoinType.INNER);
Path<Child> childCondition2 = root.join(Parent_.child, JoinType.INNER);

List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.and([condition1 over childCondition1],[condition2 over childCondition2,]));

另一种选择(预先使用JPA 2.1,可能更有效):

Path<Child> childCondition1 = root.join(Parent_.child, JoinType.INNER);
    childCondition1.on([condition1 over childCondition1]);
Path<Child> childCondition2 = root.join(Parent_.child, JoinType.INNER);
    childCondition2.on([condition2 over childCondition2]);