728x90
문제 상황
@Modifying
@Query("UPDATE Post p SET p.likes = p.likes + CASE WHEN : increment = true THEN 1 ELSE -1 END " +
"WHERE p.id = :postId")
int updateLikeCount(@Param("postId") UUID postId, @Param("likeStatus") boolean likeStatus);
위와 같이 @Query 어노테이션을 사용해서 JPQL을 사용하고 있었습니다. 그런데 아래와 같이 ['+', '-' <expression>, <identifier>, END, or FUNCTION expected, got '-' ] 에러가 발생했습니다.
이는 JPQL은 기본 SQL에 비해 더 제한된 기능을 제공하기 때문에 문제가 발생하는 것입니다.
JPQL에서 CASE WHEN 구문을 사용하여 값을 동적으로 업데이트하려고 할 때, + 또는 - 연산자를 함께 사용하는 방식이 지원되지 않습니다. 이로 인해 + 또는 - 연산자 관련 오류가 발생하는 것입니다.
즉, JPQL은 CASE WHEN 자체는 지원되지만, 이를 조건부로 값을 더하거나 빼는 산술 연산에서 사용하는 것은 지원되지 않습니다.
JPQL
@Modifying
@Query("UPDATE Post p SET p.likes = CASE WHEN :likeStatus = true THEN p.likes + 1 ELSE p.likes - 1 END " +
"WHERE p.postId = :postId AND (p.likes > 0 OR :likeStatus = true)")
int updateLikeCount(@Param("postId") UUID postId, @Param("likeStatus") boolean likeStatus);
아예 방법은 없는 것은 아닙니다. 위와 같이 likes 필드의 값을 직접 조건에 맞게 업데이트하는 방식으로 쿼리를 작성할 수 있습니다. 그러나 CASE WHEN을 통해 값을 동적으로 업데이트하려는 시도가 JPQL에서는 허용되지 않거나 오류가 발생할 수 있습니다.
nativeQuery
@Modifying
@Query(value = "UPDATE p_posts SET likes = likes + CASE WHEN :likeStatus THEN 1 ELSE -1 END " +
"WHERE post_id = :postId AND (likes > 0 OR :likeStatus = true)",
nativeQuery = true)
int updateLikeCount(@Param("postId") UUID postId, @Param("likeStatus") boolean likeStatus);
따라서 위와 같이 nativeQuery = true 옵션을 설정하여 JPQL이 아닌 네이티브 쿼리로 설정하면 보다 편하게 CASE WHEN이나, 복잡한 연산을 쉽게 사용할 수 있습니다.
'TIL,일일 회고' 카테고리의 다른 글
[TIL, 일일 회고] 2024.10.06 - AWS S3 요청 객체 (1) | 2024.10.06 |
---|---|
[TIL, 일일 회고] 2024.10.05 - @Test 어노테이션이란❓ (0) | 2024.10.05 |
[TIL, 일일 회고] 2024.10.03 - GitHub Merge 이슈 재활용 (이슈번호와 제목을 함께 가져오는 방법) (1) | 2024.10.03 |
[TIL, 일일 회고] 2024.10.02 - nativeQuery란 무엇일까❓ : JPQL vs Native Query 성능 비교하기 (1) | 2024.10.02 |
[TIL, 일일 회고] 2024.10.01 - SQL dialect is not configured 에러 해결하기 (0) | 2024.10.01 |