【问题标题】:JPA and JPQL LIMIT when used in subquery在子查询中使用 JPA 和 JPQL LIMIT
【发布时间】:2015-08-05 09:58:18
【问题描述】:

首先我想指出我知道如何在 SQL 中使用 LIMIT 来做到这一点,但是因为 JPQL 不允许 LIMIT 关键字,因此我的问题是:

我有一个返回地点及其链接标签的 JPQL 查询:

List<Object[]> p = entityManager.createQuery("
SELECT p, t.tagName
FROM Place p LEFT JOIN .... ...

例如,这可能会返回 地点1 |标签1 地点1 |标签2 地点1 |标签3 地点2 |标签1 地点2 |标签4

现在.. 我显然不能简单地返回完整的数据库位置.. 我不能简单地在任务结束时放一个 LIMIT 因为我返回标签所以我不知道有多少行等..

在 SQL 中我会做这样的事情

SELECT p.name, t.tag_name FROM ... WHERE p.idPlace IN (SELECT p.idPlace FROM ... WHERE... LIMTI 10);

我会进行子查询并使用其中的 LIMIT 来仅选择我想要的位置。

但是因为 JPQL 不允许 LIMIT,所以现在我要做的是第二次数据库调用来检索我想要的 placeIds 并使用 entityManager setMaxResult。限制。然后我将这些 Id 输入到另一个查询中。

是否有对 JPA 更有经验的人告诉我这是否是一个好习惯?有没有其他方法可以做这些事情而不必进行 2 个单独的数据库调用?

Ps:我直接在查询中选择 t.tagName 的原因是因为集合 PlaceTag(在 Place 实体内)是 LAZILY 初始化的,如果我在 java 中访问它,它将触发一个额外的数据库调用。我做到了我曾尝试像这样使用 JOIN FETCH:

List<Place> places = entityManager.createQuery("" +
                "SELECT p FROM Place p " +
                "JOIN FETCH p.PlaceTag pt " +
                "JOIN FETCH pt.tag t").setMaxResults(10).getResultList();

所以我可以在 java 中做这样的事情(访问 p.getPlaceTag() 和 getTag() 时不会触发新数据库

for (Place p : places) {
  for (PlaceTag pt: p.getPlaceTag())
      System.out.println(pt.getTag().getTagName());
}

但我收到有关查询的此错误:

查询指定连接抓取,但是抓取的所有者 选择列表中不存在关联

谢谢!

【问题讨论】:

    标签: sql hibernate jpa hql limit


    【解决方案1】:
     String query =   "SELECT p FROM Place p "
                      + "JOIN p.PlaceTag pt " 
                      + "JOIN pt.tag t";
     List<Place> places = entityManager.createQuery(query)
                          .setMaxResults(10)
                          .setFirstResult((pageNumber-1) * pageSize)
                          .getResultList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-04
      • 2015-10-02
      • 2015-07-15
      • 2014-01-17
      • 2017-11-30
      • 2020-06-05
      • 2017-11-28
      相关资源
      最近更新 更多