JPA标准:构建与集合

时间:2017-09-24 10:34:28

标签: java jpa

我正在尝试通过JPA CriteriaBuilder构建一个查询,以查找在给定值列表中具有其id的所有对象。

这就是我创造的:

protected <T> Specification<T> equalsToAnyId(Set<Long> ids) {
        return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream()
                .filter(a -> Collections.singletonList("id").contains(a.getName()))
                .map(a -> builder.in(
                        root.get(a.getName())).value(ids))
                .toArray(Predicate[]::new)
        );
    }

这似乎与任何记录(空结果集)都不匹配。怎么了?

1 个答案:

答案 0 :(得分:1)

这似乎是编写简单IN过滤器的一种非常复杂的方式。除非您正在编写某种DAO框架,否则为什么接受root, builder, query并在整个查询只占用几行时返回Specification

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(entityClass);
Root<T> root = cq.from(entityClass);
cq.where(root.get("id").in(guids));
return getEntityManager().createQuery(cq).getResultList();

如果您想保留方法签名,请执行以下操作:

protected <T> Specification<T> equalsToAnyId(Set<Long> ids) {
    return (root, query, builder) ->  builder.or(builder.in(root.get("id")).value(ids));
}

虽然你没有指定Specification是什么(JPA规范中没有这样的类)。

通常,如果您不确定为什么查询不返回您期望的数据,请通过persistence.xml中的提供程序特定属性打开SQL日志记录,例如: hibernate.show_sql用于休眠,或者通过启用持久性提供程序的调试/精细日志记录,例如: org.hibernate.SQL

作为旁注:是的,我们都很高兴java终于拥有lambdas,但这并不意味着我们必须对所有的事情进行lambda :)尤其是你如何流式传输/过滤/映射元模型以获得{{ 1}} ......让我觉得奇怪。