update memberset username=?where age < ?update memberset username=NULLwhere age < ?
m = Member(id=3, username=비회원, age=10)
m = Member(id=4, username=비회원, age=20)
m = Member(id=5, username=member3, age=30)
m = Member(id=6, username=member4, age=40)
JPA는 영속성 컨텍스트에 엔티티를 올려놓는다.
벌크 연산을 하게 되면 모든 데이터가 영속성 컨텍스트에 올라가게 된다.
그런데 벌크 연산은 영속성 컨텍스트를 무시하고 바로 쿼리를 보낸다.
따라서 DB 상태와 영속성 컨텍스트의 상태가 달라진다.
@SpringBootTest@TransactionalpublicclassQuerydslBasicTest { @TestvoidbulkUpdate() {long count = queryFactory.update(member).set(member.username,"비회원").where(member.age.lt(28)).execute();List<Member> result = queryFactory.selectFrom(member).fetch();for (Member m : result) {System.out.println("m = "+ m); } }}
m = Member(id=3, username=member1, age=10)
m = Member(id=4, username=member2, age=20)
m = Member(id=5, username=member3, age=30)
m = Member(id=6, username=member4, age=40)
만약 벌크 연산 후 조회 로직을 넣는다면?
이미 영속성 컨텍스트에 해당 id로 값이 있기 때문에 영속성 컨텍스트의 데이터가 우선적으로 보여진다.
즉, DB에 비회원이라고 업데이트된 것과는 다른 값이 출력된다.
@SpringBootTest@TransactionalpublicclassQuerydslBasicTest { @TestvoidbulkUpdate() {long count = queryFactory.update(member).set(member.username,"비회원").where(member.age.lt(28)).execute();em.flush();em.clear();List<Member> result = queryFactory.selectFrom(member).fetch();for (Member m : result) {System.out.println("m = "+ member1); } }}
m = Member(id=3, username=비회원, age=10)
m = Member(id=4, username=비회원, age=20)
m = Member(id=5, username=member3, age=30)
m = Member(id=6, username=member4, age=40)