쿼리 한번으로 대량의 데이터를 수정
@Test
public void buildUpdate() {
long result = queryFactory
.update(member)
.set(member.username, "비회원")
.where(member.age.lt(28))
.execute();
em.flush();
em.clear();
List<Member> members = queryFactory
.selectFrom(member)
.orderBy(member.age.asc())
.fetch();
assertThat(result).isEqualTo(2);
assertThat(members.get(0).getUsername()).isEqualTo("비회원");
assertThat(members.get(1).getUsername()).isEqualTo("비회원");
assertThat(members.get(2).getUsername()).isEqualTo("member3");
assertThat(members.get(3).getUsername()).isEqualTo("member4");
}
벌크 연산 시 항상 주의 할 점은 벌크 연산은 영속성 컨텍스트와 상관없이 DB에 바로 쿼리가 나가기 때문에 영속성 컨텍스트에 바뀐 데이터가 반영되지 않는다.
트랜잭션과 락 관련 용어 같은데 흐음
그런데 영속성 컨텍스트를 초기화 하지 않아도 select 쿼리가 나갔는데 왜 DB 값으로 변경하지 않나?
그렇기 때문에 항상 벌크 연산 후에 영속성 컨텍스트를 비워주는 것이 좋다.
@Test
public void bulkAdd() {
long resultCount = queryFactory
.update(member)
.set(member.age, member.age.add(1))
.execute();
assertThat(resultCount).isEqualTo(4);
}
@Test
public void bulkDelete() {
long resultCount = queryFactory
.delete(member)
.where(member.age.gt(18))
.execute();
assertThat(resultCount).isEqualTo(3);
}