Критерии гибернации с нумерацией страниц возвращают неправильные страницыJAVA

Программисты JAVA общаются здесь
Anonymous
Критерии гибернации с нумерацией страниц возвращают неправильные страницы

Сообщение Anonymous »

Вот специальный запрос, который возвращает авторов, продавших хотя бы одну книгу:

Код: Выделить всё

public class ExtendedAuthorRepositoryImpl implements ExtendedAuthorRepository {

@PersistenceContext protected EntityManager entityManager;

@Override
public Page findAuthorsWithSoldBooks(
String queryExpression, String sortExpression, @NonNull Pageable pageable) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery query = builder.createQuery(AuthorDAO.class);

final Root root = query.from(AuthorDAO.class);
final Join book =
root.join(AuthorDAO_.BOOKS, JoinType.INNER);

final List predicates = new ArrayList();
predicates.add(builder.greaterThan(book.get("soldCount"), 0));

// fetch the authors as per the page limit
final List result =
entityManager
.createQuery(query)
.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize())
.getResultList();

// create count query
final CriteriaQuery countQuery = builder.createQuery(Long.class);
final Root rootCount = countQuery.from(AuthorDAO.class);
countQuery
.select(builder.count(rootCount))
.where(builder.and(predicates.toArray(new Predicate[predicates.size()])));

// fetch the count of all authors as per given criteria
final Long authorCount = entityManager.createQuery(countQuery).getSingleResult();

// return the page
return new PageImpl(result, pageable, authorCount);
}
Вот запрос, сгенерированный Hibernate (я запускал его в SQL Developer, и он работал как положено):

Код: Выделить всё

select
c1_0.id,
c1_0.name,
c1_0.surname,
c1_0.birth_date,
c1_0.biography
from author c1_0
join book c2_0 on c1_0.id=c2_0.author_id
where c2_0.sold_count > 0
offset ? rows fetch first ? rows only
Вот результат приведенного выше запроса в SQL Developer:

Код: Выделить всё

1 John   Smith    1970-08-08 Biography 1
2 Peter  Williams 1966-01-15 Biography 2
3 Arthur Mitchel  1981-04-22 Biography 3
4 Dave   Bronson  1988-09-01 Biography 4
Наконец, в своем тесте я попытался получить 2 страницы размера 2:

Код: Выделить всё

final int pageSize = 2;
final int totalPages = 2;
final List content = IntStream.range(0, totalPages)
.mapToObj(page -> authorApi.getAuthorsWithSoldBooks(null, null, page, pageSize))
.map(AuthorsPaged::getContent)
.flatMap(List::stream)
.toList();

assertThat(content).hasSize(4); // this fails as content has size 3
Проблема в том, что при первом вызове findAuthorsWithSoldBooks() getResultList() возвращает только первую запись вместо первых двух записей Затем во втором вызове findAuthorsWithSoldBooks() getResultList() возвращает первые 2 записи , опять вместо двух последних записей Я что-то упустил?

Подробнее здесь: https://stackoverflow.com/questions/789 ... rong-pages

Вернуться в «JAVA»