본문 바로가기

Language/Java, Android

[ERROR] Can not issue data manipulation statements with executeQuery(). @Modifying 사용하기

Can not issue data manipulation statements with executeQuery().

 

Servlet.service() for servlet [dispatcherServlet] in context with path threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet] with root cause

 

 
@Query(value = "update hashtag set posting_count = posting_count + 1, total_count = total_count + 1 where tag_id = ?1 ", nativeQuery = true)
 
void countUp(long userId);

JPA를 이용하여 카운트, 또는 조회수를 카운트하다가 위와 같은 오류가 발생하였다.

 

이 오류는 UPDATE, INSERT, DELETE문을 사용할 때 executeUpdate()로 전송하지 않았을 경우에 발생한다고 한다.

 

일반적으로 UPDATE, INSERT, DELETE문이 리턴값을 갖지 않기 때문에 발생하는 에러이다.

 

그래서 executeUpdate() 메서드의 리턴값은 쿼리를 전송해서 변화한 행의 갯수이다. 글 삭제나 변경같은 일반적인 경우에는 단 하나만 삭제되기 때문에 1이 반환될 것이고, 카테고리를 삭제한다면 가지고 있던 글들이 전부 삭제되어야 하기 때문에 리턴값이 조금 크게 나올 것이며, 의미없는 쿼리를 보낸다면 삭제할 일이 없을 것이기 때문에 0이 리턴될 것이다.

 

원인을 읽어보면 의외로 해답은 간단하다. executeQuery() 대신 executeUpdate()로 쿼리를 전송하거나, executeUpdate() 대신 executeQuery()로 쿼리를 전송하면 된다.

 

@Modifying 어노테이션을 붙이지 않으면 결과값 응답을 기대하는 executeQuery() 함수를 사용하게 되는데 delete 쿼리 결과에는 결과값이 없으니 오류가 발생하는 것이다. 따라서 insert, update, delete 쿼리를 실행할 때는 executeUpdate() 함수를 사용하도록 @Modifying 어노테이션을 사용해야 한다.



또한 update 나 delete 쿼리 수행시 @Transactional 어노테이션을 함께 붙여줘야 javax.persistence.TransactionRequiredException 오류를 피할 수 있다.

 

 

 
@Modifying(clearAutomatically = true)
 
@Query(value = "update hashtag set posting_count = posting_count + 1, total_count = total_count + 1 where tag_id = ?1 ", nativeQuery = true)
 
void countUp(long userId);

 

위와 같이 @Modifying 어노테이션을 이용하여 에러를 해결하였다.

 

추가적으로 clearAutomatically 옵션을 사용하였는데, 아래 설명을 보면 이해에 도움이 될 것 같다.

 

clearAutomatically

이 Attribute는 @Modifying 이 붙은 해당 쿼리 메서드 실행 직 후, 역속성 컨텍스트를 clear 할 것인지를 지정하는 Attribute 입니다. default 값은 false 입니다. 하지만 default 값인 false를 그대로 사용할 경우, 영속성 컨텍스트의 1차 캐시와 관련한 문제점이 발생할 수 있습니다.

 

 


참고: 

https://ammff.tistory.com/96

m.blog.naver.com/PostView.nhn?blogId=kgj1&logNo=221115307403&proxyReferer=https:%2F%2Fwww.google.com%2F

devhyogeon.tistory.com/4

 

[출처] https://javacoding.tistory.com/139

 

[ERROR] Can not issue data manipulation statements with executeQuery(). @Modifying 사용하기

Can not issue data manipulation statements with executeQuery(). Servlet.service() for servlet [dispatcherServlet] in context with path threw exception [Request processing failed; nested excep..

javacoding.tistory.com