Jpa 벌크 연산 주의점

장원재·2024년 5월 3일
0

jpa

목록 보기
10/11

벌크 연산이란 한번에 대량의 데이터를 수정하는 것을 뜻한다. Jpa는 영속성 컨텍스트라는 개념이 존재하기 때문에 벌크 연산 시 주의점이 있다. 아래 예제를 통해서 주의점을 살펴보자.

1. 벌크 연산 코드

    @Modifying
    @Query("update Member m set m.age = m.age + 1 where m.age >= :age")
    int bulkAgePlus(@Param("age") int age);
  • spring data jpa의 코드로 특정 나이보다 많다면 모든 Member 에 대해서 나이를 1증가하는 벌크 연산이다.

2. 테스트 코드

    @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에서 벌크 연산후 추가 로직이 있을 경우 영속성 컨텍스트를 업데이트 해주도록 하자.

profile
데이터 분석에 관심있는 백앤드 개발자 지망생입니다

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN