본문 바로가기

Kotlin

(Kotlin) JPA JPQL orderby 절 적용이 안되는 문제

  • 정렬을 하고 싶은 API를 설계 할 때 나는 2가지 방법을 생각했다
    1. DB에서 우선 정렬하고 내보낸다
    2. Sort 객체를 생성해서 Service 에서 Sorting을 시켜준다
  • 사실 가장 안전한 방법은 데이터를 가져온 다음에 Sort객체를 가져와서 Sorting을 시켜주는 것인데 JPQL도 연습할 겸 해서 이번에는 1번 방법으로 사용하였다
    @Transactional
    override fun getTodoListSorted(sortRequestDto: SortRequestDto): List<TodoListResponseDto> {
    
    	if(sortRequestDto.sortBy) = return todoRepository.findTodoListSortedAsc(sortRequestDto.columnName).map { it.toListResponse() }
    
    	return todoRepository.findTodoListSortedDesc(sortRequestDto.columnName).map { it.toListResponse() }
    
    }

 

  • 서비스에서 해당 로직을 작성해준다
interface TodoRepository: JpaRepository<Todo, Long> {

	@Query("SELECT t FROM Todo t ORDER BY :columnName ASC")
    fun findTodoListSortedAsc(@Param("columnName")columnName String): List<Todo>

	@Query("SELECT t FROM Todo t ORDER BY :columnName DESC")
    fun findTodoListSortedDesc(@Param("columnName")columnName String): List<Todo>
}

 

  • 이런 식으로 컬럼 이름을 받아서 해당 이름 기준으로 오름 차순과 내림 차순을 하는 방법으로 구현해봤다

 

  • 실행 자체도 정상적으로 작동을 하고 로그에서도 정상적으로 Desc, Asc가 출력 되는 것을 확인했는데 데이터가 Sorting이 되지 않았다

 

  • 무슨일인가 싶어서 찾아보니까
  • JPQL은 컬럼 이름 기입란에 변수로 작성을 지원하지 않는다고 한다

 

  • 해당 부분을 확인하고 그냥 다시 2번째 방법으로 작성을 하고 확인을 했더니 정상 정렬 확인했다
 @Transactional
    override fun getTodoListSorted(sortRequestDto: SortRequestDto): List<TodoListResponseDto> {

         val sort = Sort.by(if(sortRequestDto.sortBy) Sort.Direction.ASC else Sort.Direction.DESC, sortRequestDto.columnName)

        return todoRepository.findAllBy(sort).map { it.toListResponse() }
    }

 

  • 결론
    • JPQL은 컬럼 명을 변수로 사용을 못하기 때문에 해당 부분을 사용하고 싶으면 서비스 로직으로 가지고 와서 처리를 해야 한다