[JPA] ResultSet Exception과 @Modifying에 대해...

iniestar·2022년 6월 17일
0

1.개요

@Modifying 어노테이션 이란?
@Query 어노테이션으로 작성된 메소드 쿼리에서 select를 제외한 insert, update, delete 쿼리를 실행할 때 필요한 어노테이션이다. 실제로 Spring에서는 @Modifying 어노테이션을 강제하고 있다.

@Query는 JPA의 쓰기 지연 저장소에 접근하지 않고 바로 DB에 접근한다. 여기서 우리가 간과한 점은 JPA는 영속성 컨텍스트를 유지하려는 성질을 갖고 있다는 것이다. @Query 이후에 변경된 엔티티에 대해서 우리는 영속성 컨텍스트를 관리할 의무가 있다. 이러한 변경점에 대해 동기화를 시켜주는 @Modifying이 필요한 것이다.

2. 문제점

예) @Query 사용하여 delete를 시도했을 때 아래와 같은 오류가 나타난다.

@Query("delete * from users where user_id = 'test')
----------------------------------------------------
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.QueryExecutionRequestException: 
Not supported for DML operations [delete com.baeldung.boot.domain.User u where u.active = false]
(...)

위에서 언급하였던 영속성 컨텍스트를 유지시켜야 하지만 예제에서는 영속성에 대한 관리를 하지 않고 있다.

3. 해결방법

영속성을 유지시키는 방법에는 트랜잭션을 설정하는 방법이 있으며 @Query를 사용할 때는 @Modifying을 붙여줌으로써 트랜잭션을 관리할 수 있게 된다.

@Query("delete * from users where user_id = 'test')
@Modifying

Note. @Modifying 어노테이션을 설정 후 쿼리를 실행시켜 DB에는 반영이 됐지만 다시 검색했을 때 값이 그대로인 경우?
-> 이 경우는 영속성 컨텍스트에서 저장되고 있던 값이 초기화 되지 않고 그대로 남아 있는 경우로써 @Modifying의 clearAutomatically 옵션을 설정해야 영속성 컨텍스트가 clear 되면서 정상적인 DB값이 반영된다!

@Query("delete * from users where user_id = 'test')
@Modifying(clearAutomatically=true)
profile
while(true) { 손가락 관절염++ };

0개의 댓글