[JPA] JPQL로 생성한 Delete 메서드 오류 : Statement.executeQuery()

손은실·2022년 7월 16일
0

Spring Boot

목록 보기
12/13
post-thumbnail

1. 상황

JPQL로 Delete문을 만들어 사용했더니

Statement.executeQuery() cannot issue statements that do not produce result sets.

라는 에러가 발생했다.

해석해보면, "Statement.executeQuery()는 결과 집합을 생성하지 않는 문을 실행할 수 없습니다." 라고 한다.

무슨 말일까?

Statement?

Statement 객체는 SQL을 DB로 전송하기 위해 사용한다.
Statement 인터페이스는 SQL을 실행하기 위한 3가지 종류의 메소드를 제공한다.

쿼리문 마다 다른 메소드

  1. executeQuery()
  • ResultSet 반환
  • SELECT 에서 사용

  1. executeUpdate()
  • 해당되는 레코드의 개수를 int 값으로 반환
  • CREATE, DROP, ALTER, INSERT, UPDATE, DELETE 에서 사용

  1. execute()
  • executeQuery, executeUpdate 둘 다 가능
  • boolean 값 반환

2. 원인

에러 내용 그대로다.

Statement.executeQuery()는 ResultSet을 반환하는 메소드다.
즉, Select 할 때 사용하는 메소드가 호출되어 에러가 난 것이다.

executeQuery()가 호출되었을까?
데이터 변경이 일어나는 Insert, Update, Delete 쿼리를 JPQL로 작성해 사용할 때 필요한 @Modifying 어노테이션을 달아주지 않았기 때문이다.


3. 해결

해당 메서드에 @Modifying@Transactional 어노테이션 붙이기


@Modifying

@Query 어노테이션으로 작성된 Insert, Update, Delete 쿼리 메소드를 사용할 때 필요한 어노테이션이다.

@Modifying 어노테이션이 붙은 쿼리 메소드는 영속성 컨텍스트를 거치지 않고 바로 DB에 반영된다.

이때 영속성 컨텍스트와 DB 간의 동기화 문제가 발생할 수 있어 동기화를 해주는 작업이 필요하다.


@Transactional

DB와 관련된 트랜잭션이 필요한 클래스, 서비스, 메소드에서 사용하는 어노테이션이다.

일련의 작업들을 묶어서 하나의 단위로 처리하고 싶을 때 이 어노테이션을 붙이면 된다.


도움 받은 글

execute / executeQuery / executeUpdate 차이
[삽질 피하기] @Query, @Modifying, @Transactional 어노테이션 사용법
@Modifying

0개의 댓글