Я пытаюсь получить данные, используя Hibernate Criteria API, где я строю свои критерии, и мне нужно разбить их на страницы, таким образом получить счетчик всех строк.
Проблема, с которой я сталкиваюсь, заключается в том, что, если я пытаюсь считать данные с помощью:
criteria.setProjection(Projections.rowCount());
Integer count = (Integer)criteria.uniqueResult(); // or criteria.list().get(0) = same
, а для выборки данных я добавляю эти свойства в свои критерии
criteria.setProjection(null);
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
/*
* Problematic part, if I do .list() now, I get many more rows fetched
* it's because ROOT_ENTITY has @ManyToMany
*/
List<T> lister = criteria.list();
criteria.setMaxResults(pageable.getPageSize());
criteria.setFirstResult((int) pageable.getOffset());
List<T> list = criteria.list(); // Fetches 10 (or whatever pageSize is)
Дело в том, мой count < lister.size()
, и тут возникает реальная проблема.
Допустим, я получил count = 50
, но lister.size()
- если бы я не применял нумерацию страниц, это гораздо больше, скажем100. Я могу отображать нумерацию страниц для пользователя только до 50.
Я не могу использовать lister.size()
в качестве "общего количества" для нумерации страниц, поскольку он выбирает ненужные данные только для того, чтобы сделать для них размер.
Когда я наблюдал за запросами, мой запрос подсчета просто не СОЕДИНЯЕТСЯ с этой ассоциацией @ManyToMany, а мой запрос выборки-данных - после того, как я выполнил пару строк, которые не должны изменять запрос, кроме этих setMaxResults и setFirstResult.
Мне нужно только выбрать данные из таблицы A, игнорировать ассоциацию @ManyToMany
, чтобы получить только эти 50 строк.Ассоциация также имеет FetchType.LAZY
, я даже пытался добавить FetchMode.SELECT/SUBSELECT
, которые не нужны с LAZY, не помогло, запрос всегда Критерии всегда приводят к СОЕДИНЕНИЮ с таблицей B.
Также я пытался setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
;но с разбивкой на страницы это работало так же, как «фильтр после выборки данных», поэтому, если запрос привел к первым 10 строкам, имеющим только 3 объекта DISTINCT таблицы A, в моем результирующем списке было только 3 объекта.Примерно так: при выполнении запроса вручную он возвращает:
A.prop1 | B.prop1
XXX | 1
XXX | 2
XXX | 3
YYY | 1
YYY | 2
ZZZ | 1
ZZZ | 2
CCC | 1
CCC | 2
EEE | 1
С setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
и setMaxResults(5);
- скажем, 5 (размер страницы), мой список содержит только 2 объекта (XXX, YYY), даже когда мне нужноих 5 для моей страницы.
Так чего же мне нужно достичь.Мне нужно получить количество различных значений в моей таблице A (именно это и делает мой счет), а также получить различные значения из моего запроса выборочных данных, который, как ни странно, соединяется почти со всем, что имеет мой класс DTO A, без измененияКритерии для любого присоединения вообще.