Как создать запрос критериев с помощью AVG и GROUP с использованием JPA

#sql #hibernate #jpa-2.0 #criteria

#sql #спящий режим #jpa-2.0 #критерии

Вопрос:

Я хотел получить список продуктов на основе среднего рейтинга клиента, используя запрос критериев. Я написал фрагмент кода с использованием агрегированных функций запроса критериев AVG и сохранил предложение GROUP BY. Но почему-то я получаю исключение «Не группа по выражению». Я пытался и искал в 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();
  

Комментарии:

1. Вы получаете какие-либо исключения? Не могли бы вы предоставить фактический SQL, сгенерированный из журнала?

2. @Sujitmohanty30 «javax.persistence. Исключение PersistenceException: org.hibernate.exception. Исключение SQLGrammarException: ORA-00979: не группируется ПО выражению»

3. Что ж, сообщение об ошибке довольно простое. Очевидно, что вы не можете SELECT использовать столбцы, которых у вас нет GROUP BY

4. Просто используйте тот же список выражений в cq.multiselect() и cq.groupBy()

5. @crizzis Да, я неправильно сохранил ГРУППУ. Теперь я понял. Спасибо за помощь

Ответ №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();