관리 메뉴

피터의 개발이야기

[Kotlin] Paging query needs to have a Pageable parameter 문제 해결 본문

Programming/Kotlin

[Kotlin] Paging query needs to have a Pageable parameter 문제 해결

기록하는 백앤드개발자 2024. 8. 21. 10:10
반응형

ㅁ 들어가며

 Reason: Paging query needs to have a Pageable parameter; 
Offending method: public abstract org.springframework.data.domain.Page

ㅇ Spring Data JPA를 사용하여 페이징 쿼리를 실행할 때 발생하는 오류 메시지이다.

ㅇ"Paging query needs to have a Pageable parameter"는 페이징 기능을 사용하려면 Pageable 파라미터가 필요하다는 의미이다.

ㅇ 이 문제를 해결하기 위해서는 리포지토리 메서드에 Pageable 파라미터를 추가해야 한다.

ㅇ 페이징 처리는 [Kotlin] Spring Boot와 Kotlin으로 QueryDSL 페이징 처리하기

 

ㅁ Import 확인

import org.springframework.data.domain.Pageable; ( ㅇ )
import java.awt.print.Pageable; ( X )

ㅇ 동일명의 다른 객체를 Import를 한 경우 에러가 발생한다.

 

ㅁ Repository 인터페이스 수정

import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository

interface EntityNameRepository : JpaRepository<EntityName, Long> {
    fun findBySomeField(someField: String, pageable: Pageable): Page<EntityName>
}

ㅇ 페이징 기능을 사용하고자 하는 리포지토리 메서드에 Pageable 파라미터를 추가해야 한다.

ㅇ 예를 들어, 엔티티 EntityName에 대한 리포지토리가 있다고 가정할 때, Pabeable을 추가하면 된다.

 

ㅁ 커스텀 Repository에 abstract 확인

import com.querydsl.jpa.impl.JPAQueryFactory
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Repository

@Repository
abstract class EntityNameRepositoryImpl(  // abstract를 제거 해야 한다.
    private val jpaQueryFactory: JPAQueryFactory
): EntityNameRepositoryCustom {
	override fun findBySomeField(someField: String, pageable: Pageable): Page<EntityName> {
    	// TODO paging
    }
}

ㅇ 추상 클래스인 경우 객체 자체를 인스턴스화 하지 못하여 pageable을 참조하지 못하는 경우가 있다.

ㅇ runtime 시 추상화 오류가 아닌 pagable 오류만 나타나 추상화로 인한 문제점을 인식하지 못할 수 있다.

ㅇ 나의 경우는 이 상황이어서 원인을 해결하는데 상당 시간이 필요했다.

 

ㅁ 서비스 레이어에서 Pageable 사용

import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Service

@Service
class EntityNameService(private val entityNameRepository: EntityNameRepository) {

    fun getEntitiesBySomeField(someField: String, page: Int, size: Int): Page<EntityName> {
        val pageable = PageRequest.of(page, size)
        return entityNameRepository.findBySomeField(someField, pageable)
    }
}

ㅇ 서비스 레이어에서 리포지토리 메서드를 호출할 때 Pageable 객체를 생성하여 전달한다.

 

ㅁ 컨트롤러에서 Pageable 파라미터 받기

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
class EntityNameController(private val entityNameService: EntityNameService) {

    @GetMapping("/entities")
    fun getEntities(
        @RequestParam someField: String,
        @RequestParam page: Int,
        @RequestParam size: Int
    ): Page<EntityName> {
        return entityNameService.getEntitiesBySomeField(someField, page, size)
    }
    
    // Pageable 직접 받는 방법
    @GetMapping("/entities")
    fun getYourEntities(pageable: Pageable): Page<YourEntity> {
        return yourEntityService.getYourEntities(pageable)
    }
}

ㅇ 컨트롤러에서 클라이언트로부터 페이지 번호와 크기를 받아 서비스 레이어에 전달한다.

ㅇ 컨트롤러에서 Pageable 객체를 직접 받을 수도 있다.

ㅇ Spring MVC는 자동으로 Pageable 객체를 생성해준다.

 

ㅁ 함께 보면 좋은 사이트

JPA Repository에서 Paging query needs to have a Pageable parameter 에러 발생 해결

[Spring] repository와 페이징 오류

반응형
Comments