JPA에서 벌크 연산이란, 여러 건(대량의 데이터)을 한 번에 수정하거나 삭제하는 것을 뜻한다.
벌크 연산은 executeUpdate()
메소드를 사용하고, 해당 메서드는 영향을 받은 엔티티 건수를 반환한다.
//재고가 10개 이하인 상품의 가격을 10% 증가하는 벌크 연산
String queryString =
"update Product p" +
"set p.price = p.price * 1.1" +
"where p.stockAmount < :stockAmount";
int resultCount = em.createQuery(queryString)
.setParameter("stockAmount", 10)
.executeUpdate();
//나이가 70세 이상인 Member 삭제
String queryString =
"delete from Product p" +
"where p.price < :price";
int resultCount = em.createQuery(queryString)
.setParameter("price", 100)
.excuteUpdate();
- 벌크 연산은 영속성 컨텍스트와 2차 캐시를 무시하고 데이터베이스에 직접 쿼리를 날린다.
- 그렇기 때문에 기존에 영속성 컨텍스트에 있던 엔티티를 벌크 연산으로 수정하게 되면, DB는 갱신되지만 영속성 컨텍스트는 수정 전 상태에 남아있어 문제가 생길 수 있다.
- 이를 해결하기 위해선 벌크 연산 후에 해당 엔티티를 사용하지 않거나
em.clear()
를 통해 영속성 컨텍스트 초기화, 또는em.refresh()
로 재조회하여 사용해야 한다.