일단 씻고 나가자
[Spring] (org.hibernate.exception.SQLGrammarException) could not extract ResultS 본문
[Spring] (org.hibernate.exception.SQLGrammarException) could not extract ResultS
일단 씻고 나가자 2023. 11. 28. 02:36문제 상황 (에러 본문)
2023-11-28 02:04:42.056 WARN 6956 --- [nio-8080-exec-9] o.http://m.jdbc.message.server.ErrorPacket : Error: 1064-42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'limit 3' at line 1
2023-11-28 02:04:42.057 WARN 6956 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1064, SQLState: 42000
2023-11-28 02:04:42.057 ERROR 6956 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : (conn=386) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'limit 3' at line 1
해결책 (선요약)
일반적으로 query 문에서의 문법 문제, 혹은 없는 필드에 접근할 때 발생하는 에러이다.
나의 경우 JPA의 native query 메서드에 pagable을 삽입하다 발생한 문제로,
@Query의 속성인 value, countQuery 두 쿼리문이 합쳐져 하나의 쿼리문으로 나간다는 걸 알지 못한 상태에서 구문을 작성해 발생한 에러였다. value에 적힌 native query의 마지막 ; 를 제거하니 정상 작동하였다.
사건 개요
이번 해결의 경우 하나의 문제만 해결한 것이 아닌 연달아 터진 (내 실력 부족 덕분의) 에러를 하나하나 잡아가는 과정이 있었기 때문에, 좀 재밌는 경우라 기록을 남겨두려 한다.
SQL 문법 에러야 JPA 사용하다 보면 빈번히 일어나는 일인데,
native query를 처음 작성해보다 보니 동작 원리를 잘 이해하지 못한 상태여서 (어쩌면 JPA 자체 이해도가 낮거나... 어쩌면 SQL 및 DB 자체 이해도가 낮을 수도...)
해당 에러를 발생 시킨 것 같다. 하지만 나름 로그를 보고 잘 알아챈듯.
나의 메서드의 경우 이러했는데, native query를 작성하고 pagable을 넣는 과정에서 1차 에러가 났다.
알고 보니 pagable 자체에서도 sort를 받을 수 있는데, 내 api에서는 이미 url에 "sort"라는 인자가 query param으로 삽입되어 있어서 충돌이 났던 것..
어찌저찌 해결하려 구글링 도중 native query에는 paging을 위해 @Query의 옵션인 countQuery를 넣어주어야 동작하는 정보를 알게 되어서, 함께 넣고 돌려봤더니 다음과 같은 2차 에러가 발생했다.
로그를 보나 에러 메세지를 보나 SQL 문제인 거 같은데.. 잔뜩 승이 난 상태로 로그를 천천히 다시 보게 됐다.
사실 SQL 문법이 약해서 로그를 본다고 해결 될 거 같진 않았으나, 자꾸 자꾸 다시 보다 보니 좀 의아한 부분을 발견했다.
한 쿼리의 끝을 알리는 ; 을 선언해 놓고 다음에 limit 가 나오는 게.. 그것도 같은 줄에 나오는 것이 좀 아리송?
문법은 쥐뿔도 모르기에 알음알음 내 코드를 되짚어 보는데, limit 문법은 SQL에서 특정 행을 개수만큼 도출할 때 쓰이는 문법이므로 혹시 pagable 삽입 방식이 잘못 됐나 생각도 했다가,
혹시 총 행의 개수를 세는 countQuery의 구문을 잘못 작성했나 하는 의심까지 도달하게 됐다.
알고 보니 value 옵션에 작성한 쿼리든, countQuery든 하나의 SQL 구문으로 나가는데
value에 적은 쿼리를 ; 로 종료 시켰기 때문에 countQuery가 실행되지 못하고 에러를 낸 것으로 추측된다.
그래서 value의 구문 마지막에 적은 ; 를 삭제하고 countQuery까지 실행되도록 하였더니 잘 고쳐졌다.
사실 native query를 작성할 때도 비슷한 에러를 만났었다.
쿼리문을 작성하면서 줄 구분을 하면 당연히 띄어쓰기가 될 것이라 생각하고 줄의 마지막을 한 칸 안 띄고 매 줄을 작성했었는데, 마지막 한 칸을 안 띄자 다음 줄의 명령어와 이전 줄의 마지막 단어가 짬뽕이 되면서 제대로 된 SQL 문을 내보내지 못했었다.
다시 보니 좀 웃긴 에러다 ㅋㅋ ㅋㅋ 하지만 그만큼 SQL과 JPA 기초가 약하다는 걸 깨달았다..
차근차근 열심히 공부를 쌓자..