nu_s

[Spring Data JPA] 벌크성 수정 쿼리 🍀 본문

Spring Data JPA

[Spring Data JPA] 벌크성 수정 쿼리 🍀

woochii 2023. 12. 2. 22:43
728x90
반응형

벌크성 수정 쿼리

  • 데이터 한 건 씩이 아닌 모든 데이터에 일관적인 업데이트를 날려야 하는 경우를 벌크성 수정 쿼리라 한다.

JPA

public int bulkAgePlus(int age) {
    return em.createQuery("update Member m set m.age = m.age + 1 where m.age >= :age")
            .setParameter("age", age)
            .executeUpdate();
}

 

스프링 데이터 JPA

@Modifying
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
  • 순수 JPA에서는 executeUpdate()를 사용했다.
  • 스프링 데이터 JPA에서는 @Modifying 어노테이션을 사용한다.
  • 사용하지 않으면 다음과 같은 예외가 발생한다.

 

 

주의점

  • JPA에서 데이터는 영속성 컨텍스트를 통해 관리가 된다.
  • 그러나 벌크성 쿼리는 영속성 컨텍스트를 거치지 않고 데이터베이스에 직접적으로 쿼리를 보낸다.
  • 따라서 영속성 컨텍스트에 있는 엔티티의 값과 데이터베이스의 값이 다르게 나타난다.

해결 방법

  • 벌크성 쿼리를 사용하고 난 후 영속성 컨텍스트를 초기화 시켜 DB에서 새로 값을 가져오게 만들자.
@Persistence EntityManager em;

@Test
public void bulkUpdate() {
    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));

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

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

    assertThat(resultCount).isEqualTo(3);
}
  • 그러나 스프링 데이터 JPA에서는 자동으로 초기화해주는 기능을 제공한다.
@Modifying(clearAutomatically = true)
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
  • @Modifying 어노테이션에 clearAutomatically를 true로 설정해주면 된다.
  • 그러면 update 쿼리가 발생한 후 자동으로 영속성 컨텍스트를 초기화해준다.

출처 : 인프런 실전! 스프링 데이터 JPA

728x90
반응형