벌크성 수정 쿼리

순수 JPA

@Repository
public class MemberJpaRepository {

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

스프링 데이터 JPA

public interface MemberRepository extends JpaRepository<Member, Long> {

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

    • executeUpdate()를 실행한다.

    • 붙이지 않으면 getSingleResult(), getResultList()를 호출하면서 에러가 발생한다.

주의사항

  • JPA는 영속성 컨텍스트에서 엔티티를 관리한다.

  • 벌크형 연산은 이걸 무시하고 진행하기 때문에 문제가 발생할 수 있다.

  • 아직 DB에 반영이 되지 않은 상태에서 쿼리를 날려서 데이터가 서로 안맞을 수 있다.

  • 벌크 연산 직후에는 꼭 영속성 컨텍스트를 날려준다.

  • @Modifying에 옵션을 주면 clear()를 자동으로 해준다.

참고

  • JPA는 update 등의 쿼리가 있으면 영속성 컨텍스트에 있는 데이터를 먼저 flush 하고 JPQL을 실행한다.

    • memberRepository.bulkAgePlus(20)도 결국 JPQL이므로 똑같이 동작한다.

    • 따라서 memberRepository.save가 반영된 뒤 memberRepository.bulkAgePlus(20)를 실행한다.

  • JPA 대신 JDBC Template을 직접 사용하는 경우는 해당되지 않는다.

Last updated

Was this helpful?