JPA/JPA 기본

52. JPQL 벌크연산

sdafdq 2023. 11. 3. 12:00

벌크연산은 update문이나 delete 문을 말함.

 

pk를 딱 한건 찍어서 update나 delete 하는 걸 제외한 모든 update문과 delete문

 

한번에 모든 데이터를 포괄적으로 update나 delete 하는 것

 

재고가 10개 미만인 모든 상품의 가격을 10% 인상한다던지 그런 거.

 

 

저걸 JPA에서 한다고 하면

재고 10개 미만인거 조회

가격 10% 증가

commit 시점에 DB에 반영

 

근데 이거를 쿼리 한방으로 제공

 

근데 이거 그냥 sql도 있는 거 아닌가..?

그냥 딱히 조건 안주고 update 하면 다 그렇게 바뀌잖아.

int result1 = em.createQuery("update Member m set m.age = 20")
        .executeUpdate();
Hibernate: 
    /* update
        Member m 
    set
        m.age = 20 */ update Member 
    set
        age=20

 

 

하이버네이트는 insert into select문도 지원

insert하는데 select해서 가져온 걸 insert 하는 그런 거 인 듯.

 

 

벌크 연산 주의점

영속성 컨텍스트 무시하고 DB에 직접 쿼리

 

그래서 저런 점을 해결해야 한다.

예를 들어 조회해서 연봉 5천만원인 회사원의 정보를 가져왔는데,

벌크연산으로 회사원 연봉을 다 +1000만원 올렸다.

 

그런데 얘가 commit시점에 가면.. 물론 뭔가 바뀌지 않았기 때문에 DB에 쿼리가 뭔가 날라가지 않겠지만.. 근데 또 DB는 6천만원이면서 애플리케이션은 5천만원인게 데이터 정합성에 맞지 않다.

 

이럴 경우 보통 해결책이 2가지 있는데

아예 벌크연산을 먼저 실행하고 필요한 걸 조회해 오든지 하거나 

벌크 연산 수행 후 영속성 컨텍스트를 초기화 시켜버리는 것이다.

 

참고로 벌크연산도 쿼리를 날리는 거기 때문에 저 시점에 flush() 가 된다.

 

상황에 따라 둘 중 하나 해야 한다.

 

 

 

SpringDataJPA에서

@Modifying

@Query(쿼리)

해서 벌크연산 쿼리 날릴 수 있다.

 

또 @Modifying 저곳에는 옵션도 뭐 clearAUtomatically 이런 식으로 자동으로 영속성 컨텍스트 비우는 그런 옵션도 줄 수 있다.

 

 

한건의 update나 delete 같은 경우는 JPA가 제공하는 기능을 쓰면 된다.

JPA는 이런 거 보면 개개의 건을 위주로 거의 만든 듯 하다.

 

 

 

'JPA > JPA 기본' 카테고리의 다른 글

51. Named 쿼리  (0) 2023.11.03
50. 엔티티 직접 사용  (0) 2023.11.03
49. 다형성 쿼리  (0) 2023.11.03
48-2. 패치 조인의 한계  (0) 2023.11.02
48. 페치 조인 한계  (0) 2023.11.01