티스토리 뷰
원인
SpringDataJpa에서 제공하는 페이징 관련 인터페이스를 사용하면서 오류가 발생했다. 내가 생각했던 페이징의 결과와 다른 값이 반환되었다.
Repository
Member Entity의 age 필드를 기준으로 정렬하기 위하여 Repository에 메서드를 선언하였다.
public interface MemberRepository extends JpaRepository<Member, Long> {
Page<Member> findByAge(int age, Pageable pageable);
}
내가 페이징 하려는 조건은 다음과 같다.
- age가 10인 Member를 조회한다
- 각 페이지에 3개의 데이터를 출력한다
- 0번이 아닌 1번 페이지부터 출력한다
- 내림차순으로 정렬한다
위의 4가지 조건을 갖추어서 다음과 같이 코드를 작성하였다.
age가 10인 Member를 총 10개를 저장하였다.
페이징 코드를 보면 1페이지부터 3명씩 name 필드를 기준으로 내림차순 정렬하도록 코드를 작성하였다.
@Test
@DisplayName("페이징 테스트")
void pagingTest() {
memberRepository.save(new Member("memberA", 10, null));
memberRepository.save(new Member("memberB", 10, null));
memberRepository.save(new Member("memberC", 10, null));
memberRepository.save(new Member("memberD", 10, null));
memberRepository.save(new Member("memberE", 10, null));
memberRepository.save(new Member("memberF", 10, null));
memberRepository.save(new Member("memberG", 10, null));
memberRepository.save(new Member("memberH", 10, null));
memberRepository.save(new Member("memberI", 10, null));
memberRepository.save(new Member("memberJ", 10, null));
PageRequest pageRequest = PageRequest.of(1, 3, Sort.by(Sort.Direction.DESC, "name"));
Page<Member> page = memberRepository.findByAge(10, pageRequest);
List<Member> content = page.getContent();
Assertions.assertThat(content.size()).isEqualTo(3);
Assertions.assertThat(page.getTotalElements()).isEqualTo(7);
Assertions.assertThat(page.getNumber()).isEqualTo(1);
Assertions.assertThat(page.getTotalPages()).isEqualTo(3);
Assertions.assertThat(page.isFirst()).isFalse();
Assertions.assertThat(page.hasNext()).isTrue();
}
위의 코드를 실행하면 테스트에 실패하였다고 한다.
실패의 원인으로 나는 7명의 Member가 조회될 것이라 생각했지만 실제로 10명이 조회되었다고 한다. JPA의 페이징은 0페이지부터 시작을 한다. 따라서 나는 1페이지부터 조회를 하면 0페이지 데이터를 버리기 때문에 7명이 조회될 것이라 생각했다.(페이지당 3명씩 출력)
해결
0번 페이지가 아닌 곳부터 조회하더라도 총 데이터 개수와 페이지 개수는 동일하다.
0번 페이지부터 조회
1번 페이지부터 조회
2번 페이지도 동일하다.
3번(마지막) 페이지부터 조회
페이지당 3명의 Member를 출력하므로 마지막 페이지는 1명만 출력(content.size()),
마지막 페이지이므로 다음 페이지는 존재하지 않음(page.hasNext())