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);
}


- 벌크 연산에서 가장 중요한 것은 벌크 연산이 나간 뒤, DB와 영속성 컨택스트 간의 싱크가 맞지 않는 것이다.
- WHY? 벌크 연산 같은 경우 DB로 바로 쿼리가 실행되기 때문에 이전에 영속성 컨택스트를 조회한 상태라면 그 상태 그대로 있다(DB와 값이 다르다)
- 그렇기 때문에 반드시 벌크 연산 후, 영속성 컨택스트를 flush 하고, clear를 해 주어야 한다.
주의
- JPQL 배치와 마찬가지로, 영속성 컨텍스트에 있는 엔티티를 무시하고 실행되기 때문에 배치 쿼리를 실행하고 나면 영속성 컨텍스트를 초기화하는 것이 안전하다
728x90
'실전! Querydsl' 카테고리의 다른 글
| Ch04. 실무 활용(순수 JPA와 Querydsl) - 순수 JPA 리포지토리와 Querydsl (0) | 2022.01.01 |
|---|---|
| Ch03. 중급 문법 - SQL function 호출하기 (0) | 2021.12.31 |
| Ch03. 중급 문법 - 동적 쿼리(BooleanBuilder 사용) (0) | 2021.12.31 |
| Ch03. 중급 문법 - 프로젝션과 결과 반환(기본, DTO 조회, @QueryProjection) (0) | 2021.12.31 |
| Ch02. 기본 문법 - Case문, 상수, 문자 더하기 (0) | 2021.12.30 |