【问题标题】:CriteriaAPI - GroupBy - Not Generated标准 API - 分组依据 - 未生成
【发布时间】:2011-03-30 19:20:27
【问题描述】:

我正在为一件很可能非常简单的事情而烦恼, 但我就是做错了。

我的 GroupBy 子句没有被添加到 EclipseLink 生成的 SQL 中。

尝试了以下代码的许多不同顺序和变体。

public List<Orders> findOrdersEntitiesBySearch(int maxResults, int firstResult, String column1, String column2, String key, boolean searchOrder) {
    EntityManager em = getEntityManager();
    try {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Orders> cq = cb.createQuery(Orders.class);
        Root<Orders> order = cq.from(Orders.class);
        Join<Orders, Products> prod = order.join("productsCollection");

        // Where like key
        if (column1 != null && column2 != null) {
            if (searchOrder) {
                cq.where(cb.or(cb.like(cb.lower(order.get(column1).as(String.class)), "%" + key.toLowerCase() + "%"), cb.like(cb.lower(order.get(column2).as(String.class)), "%" + key.toLowerCase() + "%")));
            } else {
                cq.where(cb.or(cb.like(cb.lower(prod.get(column1).as(String.class)), "%" + key.toLowerCase() + "%"), cb.like(cb.lower(prod.get(column2).as(String.class)), "%" + key.toLowerCase() + "%")));
            }
        } else {
            if (searchOrder) {
                cq.where(cb.like(cb.lower(order.get(column1).as(String.class)), "%" + key.toLowerCase() + "%"));
            } else {
                cq.where(cb.like(cb.lower(prod.get(column1).as(String.class)), "%" + key.toLowerCase() + "%"));
            }
        }

        // Order By
        List<Order> orderByList = new ArrayList<Order>();
        orderByList.add(cb.desc(order.get("ordDate")));
        orderByList.add(cb.desc(order.get("pkOrdID")));
        cq.orderBy(orderByList);

        // Select
        cq.select(order);

        // Group by
        //cq.groupBy(order.get("pkOrdID"));
        //Expression<Integer> grouping = order.get("pkOrdID").as(Integer.class);
        Expression<String> grouping = order.get("pkOrdID").as(String.class);
        cq.groupBy(grouping);

        Query q = em.createQuery(cq);
        q.setMaxResults(maxResults);
        q.setFirstResult(firstResult);

        return q.getResultList();
    } finally {
        em.close();
    }
}

代码编译运行良好,我得到了结果,但我的 GroupBy 子句不包括在内。

作为一个令人讨厌的快速修复,我正在运行通过函数返回的列表以删除重复项,直到找到解决方案。

提前感谢您的帮助,

大卫

【问题讨论】:

    标签: java group-by eclipselink criteria-api


    【解决方案1】:

    为了清楚起见,重写为常规 JPQL 查询,您目前有这样的内容:

    SELECT o
        FROM Orders o JOIN o.productsCollection p
        WHERE ...
        GROUP BY o.pkOrdID...
    

    这里有两个问题。首先,该组是不正确的,因为选择完整对象时,您不能在单列上进行分组 - 就像与标准SQL一样,所有不是聚集的列都必须在组中列出。第二个问题是您根本不需要 group by 。请参阅下面的选项:

    由于您在这里没有使用任何聚合函数,所以您真正想要的只是:

    SELECT DISTINCT o
        FROM Orders o JOIN o.productsCollection p
        WHERE ...
    

    因此,只需从您的条件 API 查询中删除 group-by,并改用 cq.distinct(true)

    如果您确实需要对不同查询使用聚合函数进行分组,而不是根据所选对象的主键进行分组,那么在 JPA 中您可以按对象本身进行分组。一个简单的 JPQL 示例可能是:

    SELECT o, sum(p.quantity)
        FROM Orders o JOIN o.productsCollection p
        WHERE ...
        GROUP BY o
    

    在您的查询中,这将是 cq.groupBy(order)

    顺便说一句。我不知道为什么 eclipse 链接只是在这里忽略你的组而不是报告错误。你用的是哪个版本?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 2022-11-30
      • 2021-07-04
      • 1970-01-01
      • 2017-12-25
      相关资源
      最近更新 更多