构建JPA Criteria API查询 - 按集合中的元素数排序

时间:2014-01-08 20:27:14

标签: java hibernate jpa orm jpql

我在使用JPA Criteria API构建查询时遇到问题。

实体和重要财产:

@Entity
public class Post {
    @Id int id;
    @OneToMany (mappedBy = "post") Set<Comment> comments;
    //...
}

@Entity
public class Comment {
    @Id int id;
    @ManyToOne Post post;
    //...
}

我需要一个查询,它将返回按照OneToMany中的评论数量Post排序的数据库中的所有帖子。 起初我认为这可以用JPQL来实现,如:

SELECT p 
FROM Post p 
ORDER BY SIZE(p.comments) DESC

但是SIZE(...)中的函数JPQL不能用于排序。

所以,我发现了JPA Criteria API,并尝试了以下内容:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Post> cq = cb.createQuery(Post.class);
Root<Post> p = cq.from(Post.class);
cq.select(p);
cq.orderBy(cb.desc(p.get("comments")));
List<Post> resultList = em.createQuery(cq).getResultList();

通过此查询,我无法获得正确的结果。我知道我错过了size设置'评论',但不知道如何添加该部分。我对JPA Criteria API并不熟悉。该查询应如何查看按其comments字段(设置)的大小排序的所有帖子?

1 个答案:

答案 0 :(得分:6)

CriteriaBuilder.size(Expression)返回您可以在ORDER BY子句中使用的Expression<Integer>。这行代码:

p.get("comments")

..返回扩展Path<X>的{​​{1}},因此可以安全地将返回的值用作Collection.size()的参数。

但是,之前引用的代码行使用的是Path.get()的特定重载版本,这将使编译器无法推断出类型参数X.相反,类型参数将被假定为{{1 }}。 Collection.size()已将其Expression-parameter声明为&#34;参数化类型&#34;用&#34;上限&#34; Expression<X>在我的回答中,第一次引用CriteriaBuilder.size()时没有准确反映这一点,StackOverflow坚持从方法签名中删除类型。请改为查看JavaDocs! )。所以我们必须明确提供类型参数。

试试这个:

Object