Я пытаюсь разбить результат на страницы запроса с помощью hibernate и displaytag, а объекты Hibernate DetachedCriteria
делают все возможное, чтобы стоять на пути. Позвольте мне объяснить ...
Самым простым способом разбивки на страницы с помощью displaytag, по-видимому, является реализация интерфейса PaginatedList
, который, помимо прочего, имеет следующие методы:
/* Gets the total number of results. */
int getFullListSize();
/* Gets the current page of results. */
List getList();
/* Gets the page size. */
int getObjectsPerPage();
/* Gets the current page number. */
int getPageNumber();
/* Get the sorting column and direction */
String getSortCriterion();
SortOrderEnum getSortDirection();
Я подумываю выбросить мою реализацию PaginatedList в объект Criteria и позволить ему работать по этим направлениям ...
getFullListSize() {
criteria.setProjection(Projections.rowCount());
return ((Long) criteria.uniqueResult()).intValue();
}
getList() {
if (getSortDirection() == SortOrderEnum.ASCENDING) {
criteria.addOrder(Order.asc(getSortCriterion());
} else if (getSortDirection() == SortOrderEnum.DECENDING) {
criteria.addOrder(Order.desc(getSortCriterion());
}
return criteria.list((getPageNumber() - 1) * getObjectsPerPage(),
getObjectsPerPage());
}
Но это не работает, потому что вызовы addOrder()
или setProjection()
изменяют объект критерия, делая его непригодным для последующих вызовов. Я не совсем уверен в порядке вызовов, но БД выдает ошибку на getFullListSize()
, пытаясь выполнить "select count(*) ... order by ...
", что, очевидно, неправильно.
Думаю, я мог бы исправить это, создав собственный объект для отслеживания условий запроса и перестроив объект Criteria для каждого вызова, но это похоже на переизобретение еще одного колеса. Есть ли более разумный способ, возможно, копировать Критерии, изначально переданные и работающие над этой копией?
Обновление :
Похоже, что getList
вызывается первым, а getFullListSize
вызывается несколько раз после этого, поэтому, как только будет передан порядок, getFullListSize
потерпит неудачу. Было бы целесообразно нажать на базу данных только один раз (в getList
я бы сказал) и кэшировать результаты, без необходимости копировать / сбрасывать объект Criteria
, но все же ...
Обновление (снова) :
Забудьте об этом, как только я сделаю count
, я не смогу сделать select
, и наоборот. Мне действительно нужны два разных Criteria
объекта.