Hibernate JPA CriteriaQuery с предикатом count и where - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь воспроизвести результаты этого запроса в JPA / Hibernate с помощью CriteriaQuery.

select count(*) from tbl_survey where CREATED_DATE > to_date('2020-04-01', 'yyyy-mm-dd') 

Значение daysBack передается как параметр.

    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DATE, daysBack);
    Date daysAgo = cal.getTime();
    try {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
        Root<Survey> root = cq.from(Survey.class);
        Path<Date> dateCreated = root.<Date>get("createdDate");
        Predicate datePredicate = cb.greaterThanOrEqualTo(dateCreated, daysAgo);
        cq.where(datePredicate);
        cq.select(cb.count(cq.from(Survey.class)));

        long count = entityManager.createQuery(cq).getSingleResult();
        JSONObject resultJson = new JSONObject();
        resultJson.put(SURVEY_COUNT, count);

        logger.info("Count for Survey table is: {}", count);
        return new ResponseEntity<>(resultJson.toString(), HttpStatus.OK);
    } catch (Exception e) {
        logger.error(e.getLocalizedMessage(), e);
        return new ResponseEntity(e.getLocalizedMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

вывод журнала: Счетчик для таблицы Survey: 36

Однако в таблице всего 6 строк, которые подсказывают мне, что создается какое-то самосоединение или перекрестное произведение, чтобы создать результат 36. Что должен ли я поступать иначе, чтобы получить правильный счет?

1 Ответ

1 голос
/ 09 мая 2020

Самосоединение происходит для этой строки, где вы используете новый root

cq.select(cb.count(cq.from(Survey.class)));

root, используемый для того, где условие и запрос количества отличаются, что вызвало самосоединение. Используйте тот же root для запроса подсчета также

cq.select(cb.count(root)); 
...