728x90
JPQL에서 limit 1 작성했을때 실행 안되는 오류
JPA를 사용하면서 repository에서 named query로 limit 1을 사용했을 때 아예 프로젝트 실행조차 안 되는 오류가 났다.
원인 코드
- 가장 최근에 등록된 회원을 가져오고 싶어서 limit 1을 작성했다.
@Query("SELECT u from User u where u.userSn = :userSn order by u.regDt desc limit 1")
- 이때 아래와 같은 오류 메세지를 출력하면서 프로젝트 실행이 안 됐다.
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: limit near line 1, column 149 [@Query("SELECT u from User u where u.userSn = :userSn order by u.regDt desc limit 1")]
문제 원인
찾아보니 LIMIT 절은 JPQL(Java Persistence Query Language)에서는 지원되지 않는다고 한다.
JPQL은 SQL과 유사하게 보이지만, 일부 SQL 문법을 지원하지 않거나 다르게 동작하는 경우가 있다. 그중 하나가 LIMIT 절이다. LIMIT은 결과 세트에서 반환할 최대 행 수를 지정하는 SQL 문법이다. JPQL은 이러한 LIMIT 절을 직접 지원하지 않기 때문에, @Query 애노테이션에서 JPQL을 작성할 때 LIMIT를 사용하면 문법 오류가 발생한다.
문제 해결
일단 다양한 해결 방법이 있지만 그중에서 두 가지만 적어보겠다.
- Spring Data Jpa에서 제공하는 findFirstBy 또는 findTopBy 메소드 활용
- 이 메소드는 결과 중 첫 번째 레코드만 반환하는 것을 지원한다. 이렇게 하면 내부적으로 LIMIT 1과 유사한 작업을 수행할 수 있다.
- 최신 등록된 유저를 찾고 싶은 현재와 같은 케이스에서, UserSn을 기준으로 내림차순으로 정렬한 수 첫 번째 결과만 가져오게 하는 방법이 있다.
User findFirstByUserSnOrderByUserSnDesc(@Param("userSn") Integer userSn);
2. Java 코드에서 처리하기
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByUserSnOrderByRegDtDesc(Long userSn, Pageable pageable);
}
- 사용하는 쪽에서 Pageable 객체를 생성하여 첫 번째 결과만 가져온다.
Pageable topOne = PageRequest.of(0, 1);
List<User> users = userRepository.findByUserSnOrderByRegDtDesc(userSn, topOne);
User latestUser = users.get(0);
마무리
결국 난 1번 방법으로 해결했다. 하지만 단순한 조건이나 정렬이 아니라 복잡한 조건이 있는 경우에는 spring data jpa에서 제공해 주는 findFirstBy나 findTopBy를 활용하진 못했다. 이때는 아예 Java 코드에서 처리를 해야 했는데 조금 불편함이 있었다.
Custom Annotation 만들기 - 메타 어노테이션
'Spring > Spring Data JPA' 카테고리의 다른 글
JPA와 Spring Data JPA의 차이 (1) | 2024.01.02 |
---|---|
JPA N+1 문제 해결하기 (fetch join, entityGraph, batch size) (5) | 2023.12.28 |
[Spring Data JPA] ResponseDTO에 기본 생성자 있어야하는 이유 (1) | 2023.11.07 |
native query에서 @rank := 0, @rownum 처럼 사용자 정의 변수 사용할때 에러 발생 (1) | 2023.10.26 |
JPA(native query)에서 MariaDB WITH RECURSIVE 작동 안되는 오류 (1) | 2023.10.26 |