我在使用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
字段(设置)的大小排序的所有帖子?
答案 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