Как подсчитать строки в запросе с помощью критериев JPA?

Я пишу модуль, который предоставляет данные для таблицы пользовательского интерфейса, где пользователь может передать запрос JPA Criteria. Получение данных в порядке. Однако я не смог найти решение для подсчета строк из запроса, чтобы указать «длину» для таблицы.

Что я хочу сделать, так это передать запрос как подзапрос в части FROM нового запроса, но я не знаю, возможно ли это вообще с критериями.

Результирующий SQL должен быть примерно таким:

SELECT count(1) FROM <user specified query as subquery>

Во всех примерах, которые я нашел, говорилось, что я должен воссоздать запрос с тем же корнем, теми же соединениями... и т.д. И измените выбор, чтобы он содержал количество, но это намного сложнее, чем это, а также, если я это сделаю, мне придется подумать о таких вещах, как: что, если исходный запрос содержит предложение group by, как мне скопировать это в новый запрос без получения нескольких строк в результате.

Я пытался сделать это:

    CriteriaQuery countingQuery = criteriaBuilder.createQuery(Long.class);
    Root from = countingQuery.from(userSpecifiedQuery.subquery(entityClass));
    countingQuery.select(criteriaBuilder.count(criteriaBuilder.literal(1L)));

Но нет метода from, который принимает Subquery в качестве параметра.

В классе Subquery есть метод correlate, который создает Root из Subquery, который можно использовать вместо countingQuery.from(), но я не мог понять, какой корень передать методу correlate.

Java-документ говорит:

/**
 * Create a subquery root correlated to a root of the 
 * enclosing query.
 * @param parentRoot  a root of the containing query
 * @return subquery root
 */

Меня это больше смущает. Разве в моем случае корень «охватывающего» запроса не будет корнем, созданным этим методом? (А может, этот метод делает совсем не то, что я думал?)


person cs.peter    schedule 05.07.2018    source источник
comment
Проверьте это, и вы найдете свой ответ: stackoverflow.com/questions/43468272/java-hibernate-count-rows/   -  person Zorglube    schedule 05.07.2018
comment
@Zorglobe В этом ответе запрос помещен в предложение where, а не в from. В тех случаях, когда исходный запрос содержит идентификатор одного объекта, это может быть полезно, но я не могу этого предположить. Мой код мог получить запрос с несколькими соединениями или даже без возможности получить идентификаторы. (Например: агрегированный запрос)   -  person cs.peter    schedule 05.07.2018
comment
Если я правильно понял, вы просто ищете решение для подсчета строк, возвращаемых из запроса, чтобы указать длину таблицы в вашем пользовательском интерфейсе?   -  person Zorglube    schedule 05.07.2018
comment
@Zorglobe Да, это именно то, что я пытаюсь сделать.   -  person cs.peter    schedule 07.07.2018
comment
Вам просто нужно прочитать размер ответа из вашего объекта ответа.   -  person Zorglube    schedule 09.07.2018
comment
@Zorglobe Да, это вариант. Однако он будет извлекать строки из базы данных на сервер приложений, что может быть медленным, занимать много памяти и в некоторых случаях может привести к остановке приложения. Поэтому мне нужно лучшее решение. (На данный момент это то, что мы сделали, но я не доволен этим решением.)   -  person cs.peter    schedule 19.07.2018
comment
Лучшее решение эквивалентно Select Count(*) From XXX Where XXX.yyy = ...   -  person Zorglube    schedule 19.07.2018