Jeomxon's Tech Note

[Spring-Data-Jpa] 벌크연산 시 주의해야할 점(Update, Delete등) 본문

Spring/JPA

[Spring-Data-Jpa] 벌크연산 시 주의해야할 점(Update, Delete등)

저문(jeomxon) 2022. 8. 4. 01:21

spring-data-jpa에서 벌크연산을 처리할 때 주의해야할 사항은 꼭 알아둬야할 것 같아서 포스팅을 한다.

@Modifying
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);

위 코드에서 파라미터로 들어온 age보다 크거나 같은 age에 대해서는 1을 더하여 update쿼리를 날려주는 것을 알 수 있다.

 

첫번째 주의사항은 @Modifying을 써줘야한다는 것이다.

@Modifying을 쓰지 않으니깐 이런 경고문이 뜬다. update 혹은 delete쿼리를 보낼 때는 반드시 필요한 어노테이션임을 알 수 있다.

 

두번째 주의사항은 벌크연산 후 영속성 컨텍스트를 초기화 시켜줘야한다는 것이다.

위와 같은 상황이라고 가정했을 때 처음 내가 한명의 멤버에 대해서 age를 40이라고 지정해줬다.

memberRepository.save(new Member("member5", 40));

그리고 멤버 전체에 대해서 벌크연산을 진행한 후 영속성 컨텍스트에서 해당 멤버를 가져오게되면 어떻게 될까?

int resultCount = memberRepository.bulkAgePlus(20); //벌크 연산

List<Member> result = memberRepository.findByUsername("member5");
Member member5 = result.get(0);
System.out.println("member5 = " + member5);

이처럼 멤버의 age는 40으로 나온다. 분명이 Update쿼리가 날라가서 41이 됐을텐데 왜 40이 나올까?

바로 영속성 컨텍스트에서 가져왔기 때문이다.

정리하자면 벌크연산을 할 때 Update쿼리를 날리면 영속성 컨텍스트가 아니라 db에 값이 바로 update된다.

즉 영속성 컨텍스트를 거치지 않는다는 의미이다.

그 후 find를 통해서 영속성 컨텍스트에 있는 동일한 멤버를 가져오게 되면 당연히 벌크연산이 들어가기 전의 값을 가진 멤버를 반환한다.

따라서 벌크연산 이후에는 영속성 컨텍스트를 초기화 시켜줘야한다.

int resultCount = memberRepository.bulkAgePlus(20);
em.flush();
em.clear(); //영속성 컨텍스트 초기화

List<Member> result = memberRepository.findByUsername("member5");
Member member5 = result.get(0);
System.out.println("member5 = " + member5);

위와 같이 영속성 컨텍스트를 초기화한 후 다시 member를 가져오면 어떻게 되는지 확인해보자.

이렇게 find를 통해 가져오면 db에서 가져와서 영속성 컨텍스트에 올려놓고 객체로 넘겨서 가져온다.

영속성 컨텍스트를 초기화 한 후 다시 조회를 하면 db와 일치하는 값을 얻을 수 있다.

따라서 벌크연산 후에는 항상 영속성 컨텍스트를 초기화하자!

 

하지만 이렇게 매번 clear를 신경써서 하기 귀찮고 까먹을 수도 있을거라 생각했는지 spring-data-jpa에서는 추가적인 기능을 제공한다.

@Modifying(clearAutomatically = true) //Modifying에 옵션부여
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);

@Modifying에 clearAutomatically옵션을 true로 주면 항상 연산 후에 자동으로 영속성 컨텍스트를 초기화해준다.

위와 같이 사용하는 것이 가장 편하고 실용적일 것이다.

'Spring > JPA' 카테고리의 다른 글

[Spring-Data-JPA] @Query의 장점, 그리고 연관된 JPQL의 단점  (0) 2022.08.03