【问题标题】:How to Create a Criteria Query with AVG and GROUP using JPA如何使用 JPA 使用 AVG 和 GROUP 创建条件查询
【发布时间】:2021-01-19 09:06:59
【问题描述】:

我想使用 Criteria 查询根据平均客户评分获取产品列表。我使用条件查询聚合函数 AVG 编写了一段代码并保留了 GROUP BY 子句。但不知何故,我得到了 "Not a Group BY Expression" 例外。我尝试并在 Google 中搜索以解决该问题,但没有任何帮助。下面贴出代码

CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Object[]> cq = builder.createQuery(Object[].class);
        Root<GdbCustomerProductReviewImpl> productReview = cq.from(GdbCustomerProductReviewImpl.class);
        Path productPath = productReview.get("product");
        Path documentPath = productPath.get("photo");
        Path categoryPath = productPath.get("defaultCategory");
        Path productCategoryPath = categoryPath.get("prdCategory");
        cq.multiselect(productReview.get("id"),productPath.get("url"),productPath.get("skuName"),documentPath.get("id"));
        cq.where(builder.isNotNull(productPath.get("id")));
        cq.where(builder.equal(productReview.get("status"),"ACTIVE"));
        cq.where(builder.equal(productReview.get("reviewType"),"PRODUCT"));
        cq.where(builder.equal(productPath.get("isEnable"),Boolean.TRUE));
        cq.where(builder.equal(productPath.get("status"),StatusType.APPROVED.getType()));
        cq.where(builder.isNotNull(productPath.get("defSkuMap")));
        cq.where(builder.equal(productCategoryPath.get("isEnabled"),Boolean.TRUE));
        cq.groupBy(productReview.get("id"));
        Expression event_count = builder.avg(productReview.get("rating"));
        cq.orderBy(builder.desc(event_count));
        List<Object[]> resultList = em.createQuery(cq).setMaxResults(size).getResultList();

【问题讨论】:

  • 你有什么异常吗?你能提供从日志生成的实际 SQL 吗?
  • @Sujitmohanty30 "javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: ORA-00979: not a GROUP BY expression"
  • 嗯,错误信息非常简单。你不能SELECT 列你不GROUP BY,显然
  • 只需在cq.multiselect()cq.groupBy() 中使用相同的表达式列表
  • @crizzis 是的,我没有正确保存 GROUP BY。现在我明白了。感谢您的帮助

标签: sql hibernate jpa-2.0 criteria


【解决方案1】:

在进一步的研究中找到了解决方案,也感谢 crizzis。发布对我有用的解决方案。

CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Object[]> cq = builder.createQuery(Object[].class);
        Root<GdbCustomerProductReviewImpl> productReview = cq.from(GdbCustomerProductReviewImpl.class);
        Path productPath = productReview.get("product");
        Path documentPath = productPath.get("photo");
        Path categoryPath = productPath.get("defaultCategory");
        Path productCategoryPath = categoryPath.get("prdCategory");
        Expression event_count = builder.avg(productReview.get("rating"));
        cq.multiselect(productPath.get("id"),productPath.get("url"),productPath.get("skuName"),documentPath.get("id"));
        cq.where(builder.isNotNull(productPath.get("id")),builder.equal(productReview.get("status"),"ACTIVE"),builder.equal(productReview.get("reviewType"),"PRODUCT"),builder.equal(productPath.get("isEnable"),Boolean.TRUE),builder.equal(productPath.get("status"),StatusType.APPROVED.getType()),builder.isNotNull(productPath.get("defSkuMap")),builder.equal(productCategoryPath.get("isEnabled"),Boolean.TRUE));
        cq.groupBy(productPath.get("id"),productPath.get("url"),productPath.get("skuName"),documentPath.get("id"));
       
        cq.orderBy(builder.desc(event_count));
        List<Object[]> resultList = em.createQuery(cq).setMaxResults(size).getResultList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    相关资源
    最近更新 更多