벌크성 수정 쿼리

Mina Park·2022년 10월 9일
0
    @Modifying(clearAutomatically = true) //벌크연산 후 영속성 컨텍스트 초기화 필요
    @Query(value = "update Member m set m.age = m.age + 1 where m.age >= :age")
    int bulkAgePlus(@Param("age") int age);
 @Test
    public 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 resultCnt = memberRepository.bulkAgePlus(20);
//        em.clear();
        //벌크쿼리는 영속성 컨텍스트에 올리지 않고 DB에 바로 처리 하므로 같은 트랜잭션 안에서 불일치가 발생
        //따라서 벌크연산 후에는 반드시 영속성 컨텍스트를 초기화!!!

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

        //then
        assertThat(resultCnt).isEqualTo(3);
    }
  • @Modifying 어노테이션 사용
    • 벌크성 수정,삭제 쿼리 이용시 적용
    • 사용하지 않을 경우 org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations 예외 발생

📌 벌크성 쿼리 실행 후 영속성 컨텍스트 초기화

  • @Modifying(clearAutomatically = true) 어노테이션 옵션 적용
    • false가 기본값임
  • 벌크연산 뒤에 해당값을 다시 조회하는 등의 추가행위가 있을 경우에는 반드시 영속성 컨텍스트 초기화!
    • 벌크연산은 영속성 컨텍스트를 무시하고 실행하므로, 영속성 컨텍스트에 올려져있는 엔티티의 상태와 벌크연산 뒤 DB에 저장된 엔티티 상태가 달라질 수 있음
    • 권장하는 방안
      • (1) 영속성 컨텍스트에 엔티티가 없는 상태에서 벌크 연산을 먼저 실행
      • (2) 부득이 영속성 컨텍스트에 엔티티가 있을 경우 벌크 연산 직후 영속성 컨텍스트 초기화

0개의 댓글