JPA

JPA Query update @modifying

du.study 2020. 8. 26. 01:13
728x90

JPA를 사용하다보면 가끔 Bulk 업데이트를 위하여, query를 사용하여 업데이트 하는 경우가 있습니다.

그리고 이 경우, 우리는 항상 @modifying를 사용하게 됩니다.

그렇다면 어째서 @modifying를 사용해야만 하는것을까라는 궁금증이 생겼습니다.

그래서 @Query를 이용해서 업데이트 쿼리를 작성하되 @modifying를 사용, 미사용 상태로 돌려본 후, 결과를 지켜봤습니다.

우선 Repository interface에 @Modifying을 선언하지 않고 실행한 결과입니다.

@Component
public class JpaRunner implements ApplicationRunner {

    @Autowired
    private Repo repo;

    @Transactional
    @Override
    public void run(ApplicationArguments args) throws Exception {
        Account account = new Account();
        account.setUsername("dusang");
        account.setPassword("12354");
        repo.save(account);

        repo.updatePassword("testtest");
    }
}

실행 러너 코드 이후 코드에서도 변경 X

public interface Repo extends JpaRepository<Account,Long> {
    //@Modifying
    @Query("UPDATE myAccount a SET a.password = ?1")
    void updatePassword(String newPwd);

}

Repository @Modifying주석처리

매우매우 간단하게 세팅후, 실행을 해보면 다음과 같은 에러를 맞이하게 됩니다.

org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations

해당 에러를 한번 추적해보면 다음과같은 QueryTranslatorImpl이라는 곳에서 에러가 발생시키고 있습니다.

그렇다면 주석을 해제하면..?🤔

 

다음과 같은 차이로 인하여 정상 실행이 되게 됩니다.

1. JpaQueryExecution 에서 호출하는  result = doExecute(query, accessor); 에서 이전과 다른 Execution 실행

@Modifying 적용시, ModifyingExecution, 미적용시 SingleEntityExecution 호출

2. 해당 Execution에서 처리하는 로직이 다른것을 실행하면서 결과적으로 Not supported for DML operations 미발생.

 

이번 포스팅은 @Modifying를 왜 사용해야하는가 라는 부분이 궁금해서 찾아본 글이였습니다.

요걸 찾아보면서 궁금했던점은 ModifyingExecution, SingleEntityExecution를 생성하는 부분, 주입하는 부분,어떤기준으로 execution이 갈리는지..?등에 대하여 확인할 예정입니다.

 

 

728x90