JPA 변경 감지 기능만으로는 변경된 데이터가 100건이라면 100번의 UPDATE SQL 실행해야 한다.
쿼리 한 번으로 여러 테이블 로우 변경
재고가 10개 미만인 모든 상품의 가격을 10% 상승
String qlString = "update Product p " +
"set p.price = p.price * 1.1 " +
"where p.stockAmount < :stockAmount";
int resultCount = em.createQuery(qlString)
.setParameter("stockAmount", 10)
.executeUpdate();
벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 날린다.
예를들어 em.find와 같이 db에서 값을 조회할 경우
영속성 컨텍스트(애플리케이션)에서의 값과 데이터베이스에서의 값이 서로 다를 수 (꼬일 수) 있으므로
em.find 하기 전에 아래 두가지 방법 중 하나를 수행하는 것이 좋다.
벌크 연산을 먼저 실행
-> 영속성 컨텍스트에 작업을 아무것도 하지 말고 벌크 연산만 수행
-> 영속성 컨텍스트에는 당연히 아무것도 없는 상태이므로 꼬이지 않음
벌크 연산 수행 후 영속성 컨텍스트 초기화
-> 영속성 컨텍스트에 뭔가 있을 경우 벌크 연산을 수행하면 쿼리가 날라가므로 flush는 자동으로 되기 때문에
초기화(em.clear)만 해주면 꼬이지 않음