【问题标题】:Building JPA Criteria API query - sorting by number of elements in collection构建 JPA Criteria API 查询 - 按集合中的元素数量排序
【发布时间】:2014-01-27 03:39:17
【问题描述】:

我在使用 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;
    //...
}

我需要一个查询,该查询将返回 db 中按 cmets 数量排序的所有帖子(Post 中的OneToMany)。 起初我认为这可以用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();

通过此查询,我没有得到正确的结果。我知道我错过了获取集合'cmets'的size,但不知道如何添加该部分。我对JPA Criteria API 不是很熟悉。该查询应该如何查看按其comments 字段(集)的大小排序的所有帖子?

【问题讨论】:

  • 你确定这行不通吗:cq.orderBy(cb.desc(cb.size(p.&lt;Collection&gt;get("comments")))); ?
  • 否则我认为您将不得不使用SubqueryCriteriaBuilder.count(Expression)
  • @MartinAndersson 是的,你是对的,我错过了&lt;Collection&gt; 部分,所以cq.orderBy(cb.desc(cb.size(p.&lt;Collection&lt;Comment&gt;&gt;get("comments")))); 是正确的。您可以将此作为答案发布。谢谢。

标签: java hibernate jpa orm jpql


【解决方案1】:

CriteriaBuilder.size(Expression) 返回一个Expression&lt;Integer&gt;,您可以在 ORDER BY 子句中使用它。这行代码:

p.get("comments")

..返回一个扩展Expression&lt;X&gt;Path&lt;X&gt;,因此可以安全地将返回值用作 Collection.size() 的参数。

但是,前面引用的代码行使用了 Path.get() 的特定重载版本,这将使编译器无法推断类型参数 X。相反,类型参数将被假定为 Object . 但是 Collection.size() 已将他的 Expression-parameter 声明为“参数化类型”,其“上限”为 Collection这在第一次引用CriteriaBuilder.size() 在我的回答中,StackOverflow 坚持从方法签名中删除类型。请参阅 JavaDocs!)。所以我们必须明确地提供类型参数。

试试这个:

cq.orderBy(cb.desc(cb.size(p.<Collection>get("comments"))));

【讨论】:

  • 嘿马丁,你能帮我解决这个问题吗:stackoverflow.com/questions/21137719/…
  • 我问如何在 JPQL 中按集合大小写排序?
  • 如何将这种技术与 JPA Criteria API 一起使用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多