실전! Querydsl

Ch03. 중급 문법 - 수정, 삭제 벌크 연산

webmaster 2021. 12. 31. 12:34
728x90

 

@Test
@Commit
public void bulkUpdate(){
    //member1 = 10 -> DB member1
    //member2 = 20 -> DB member2
    //member3 = 30 -> DB member3
    //member4 = 40 -> DB member4

    //해당 값들이 다 영속성 컨택스에 올라가 있는 상태이다.
    //벌크 연산은 DB에 바로 쿼리를 동작시키기 때문에 DB와 영속성 컨택스트랑 데이터가 맞지 않는다.
    long count = queryFactory
            .update(member)
            .set(member.username, "비회원")
            .where(member.age.lt(28))
            .execute();
    //영속성 컨택스트에 값이 있기 때문에 DB에서 값을 가지고 와도 버리기 때문에 결과적으로 반영되지 않은 데이터를 가지고 잇다.
    //member1 = 10 -> DB 비회원
    //member2 = 20 -> DB 비회원
    //member3 = 30 -> DB member3
    //member4 = 40 -> DB member4

    em.flush();
    em.clear(); //영속성 컨택스트를 초기화 해버리면 된다.

    List<Member> result = queryFactory
            .selectFrom(member)
            .fetch();
    for(Member member : result)
        System.out.println(member);

}

Bulk Add(기존 값을 참조해서 변경하는 법)
Bulk Delete(벌크 삭제 연산)

  • 벌크 연산에서 가장 중요한 것은 벌크 연산이 나간 뒤, DB와 영속성 컨택스트 간의 싱크가 맞지 않는 것이다.
  • WHY? 벌크 연산 같은 경우 DB로 바로 쿼리가 실행되기 때문에 이전에 영속성 컨택스트를 조회한 상태라면 그 상태 그대로 있다(DB와 값이 다르다)
  • 그렇기 때문에 반드시 벌크 연산 후, 영속성 컨택스트를 flush 하고, clear를 해 주어야 한다.

주의

  • JPQL 배치와 마찬가지로, 영속성 컨텍스트에 있는 엔티티를 무시하고 실행되기 때문에 배치 쿼리를 실행하고 나면 영속성 컨텍스트를 초기화하는 것이 안전하다
728x90