Я пытаюсь выполнить разбиение на результат с помощью 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()
изменяют объект-критерий, который делает его доступным для последовательных вызовов. Я не совсем уверен в порядке вызовов, но db выдает ошибку на getFullListSize()
, пытаясь сделать "select count(*) ... order by ...
", что явно неверно.
Я думаю, что могу исправить это, создав собственный объект, чтобы отслеживать условия запроса и перестраивать объект Criteria для каждого вызова, но это похоже на повторное создание еще одного колеса. Есть ли более разумный способ, возможно, скопировав исходный критерий Крит и работающий над этой копией?
Обновление:
Похоже, что getList
вызывается первым, а getFullListSize
вызывается несколько раз после этого, поэтому, как только происходит передача заказа, getFullListSize
завершится с ошибкой. Было бы разумно ударить db только один раз (в getList
я бы сказал) и кэшировать результаты, без необходимости копировать /reset объект Criteria
, но все же...
Обновить (снова):
Забудьте об этом, как только я сделал count
, я не могу сделать select
и наоборот. Мне действительно нужны два разных объекта Criteria
.