벌크 연산이란 한번에 대량의 데이터를 수정하는 것을 뜻한다. Jpa는 영속성 컨텍스트라는 개념이 존재하기 때문에 벌크 연산 시 주의점이 있다. 아래 예제를 통해서 주의점을 살펴보자.
@Modifying
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
@Test
void bulkUpdate() {
//given
memberRepository.save(new Member("member1", 10));
memberRepository.save(new Member("member2", 19));
memberRepository.save(new Member("member3", 20));
memberRepository.save(new Member("member4", 21));
memberRepository.save(new Member("member5", 40));
//when
int resultCount = memberRepository.bulkAgePlus(20); //벌크 연산
Member member5 = memberRepository.findMemberByUsername("member5");
System.out.println("member5 = " + member5);
//then
...
}
memberRepository.bulkAgePlus(20)
를 통해서 나이가 20살 이상인 member3,4,5 는 나이가 1씩 증가하게 된다. 그러면 member5
는 나이가 41이 나오는 것을 기대할 수 있다.member5 = Member(username=member5, age=40)
@Modifying(clearAutomatically = true)
옵션을 사용하면 쿼리를 날린 후, em.clear()
를 시켜줘서 우리가 기대했던 결과를 확인할 수 있을 것이다. (영속성 컨텍스트가 업데이트 됐기 때문) @Modifying(clearAutomatically = true)
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
member5 = Member(username=member5, age=41)
따라서 Jpa에서 벌크 연산후 추가 로직이 있을 경우 영속성 컨텍스트를 업데이트 해주도록 하자.