[TIL] 23.05.30 Spring Data Jpa(2) 복습 벌크성 수정

hyewon jeong·2023년 5월 30일
0

TIL

목록 보기
127/138

벌크성 업데이트(또는 삭제)란?

  • 벌크성 업데이트 또는 삭제(Bulk Update/Delete)는 데이터베이스에서 한 번에 여러 행을 업데이트하거나 삭제하는 작업을 의미합니다.

  • 개별적으로 업데이트 또는 삭제 쿼리를 실행하는 것보다 효율적으로 작업을 수행할 수 있습니다. 예를 들어, 특정 조건을 만족하는 모든 행의 값을 일괄적으로 변경하거나 삭제할 수 있습니다.

JPA에서 벌크성 업데이트(또는 삭제) 방법

  1. EntityManager의 createQuery() 메소드를 사용하여 업데이트 또는 삭제 쿼리를 작성하고
  2. executeUpdate() 메소드를 호출하여 실행합니다. 이를 통해 한 번의 쿼리 실행으로 여러 엔티티를 업데이트하거나 삭제할 수 있습니다.
  • executeUpdate() : Jpa의 메소드 중 하나로 벌크성 쿼리에 함께 사용된다.
  • 영속성 컨텍스트를 우회하여 데이터베이스에 대한 업데이트를 직접 실행(쿼리 전달) 하고 업데이트 성공한 데이터베이스의 행의 수를 반환한다.
  • 그렇기 때문에 벌크성 업데이트 및 삭제의 경우는 데이터베이스와 영속성컨텍스트 값이 일치 하지 않을 수 있으므로 벌크성 업데이트(또는 삭제) 후 영속성 컨텍스트 초기화를 해줘야 한다. ( 벌크성 업데이트 후 데이터를 조회 하지 않는 다면 초기화를 하지 않아도 된다. 만약 다시 조회해야 하면 꼭 영속성 컨텍스트를 초기화 하자.)

1. 순수 JPA 경우

@Repository
public class MemberJpaRepository{

@PersistenceContext // entitymanager 주입하는 어노테이션 
EntityManager em; // 영속성 컨텍스트로 데이터를 관리함 

 // 순수 jpa 는 @Modifying(clearAutomatically = true)를 사용하지 않고 Entity Manager를 활용하여 데이터베이스 직접 변경 작업을 수행한다.
  public int bulkUpdate(int age){
     int resultCount = em.createQuery("update Member m set m.age = m.age+1 where m.age = :age")
        .setParameter("age",age)
        .executeUpdate(); // JPA 메소드 중 하나로 , 영속성 컨텍스트를 우회하여 직접 데이터베이스에 대한 업데이트를 실행(쿼리 전달)하고, 업데이트 실행에 성공한 행의 수를 반환한다.
                          // 그렇기 때문에 데이터베이스와 영속성 컨텍스트의 값이 일치 하지 않을 수 있다. 
    em.clear(); // 벌크성 업데이트 후 초기화하여 영속성 컨텍스트와 동기화 시킴 
    return resultCount;
  }
}

2. Spring Data JPA 경우

@Modifying(clearAutomatically = true) 
 @Query("update Member m set m.age = m.age+1 where m.age >=20")
 int bulkUpdate(@Param("age")int age);
  • @Modifying 애노테이션은
    bulkUpdate() 메소드가 데이터베이스를 수정하는 작업을 수행한다는 것을 나타냅니다. 이 애노테이션을 사용하여 Spring Data JPA는 해당 메소드를 실행할 때 트랜잭션을 시작하고, 변경 작업이 완료되면 트랜잭션을 커밋합니다.

  • 벌크성 수정, 삭제 쿼리는 @Modifying 어노테이션을 사용 사용하지 않으면 다음

org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for
DML operations

예외 발생
@Modifying(clearAutomatically = true) (이 옵션의 기본값은 false )
이 옵션 없이 회원을 findById로 다시 조회하면 영속성 컨텍스트에 과거 값이 남아서 문제가 될 수 있다.

  • clearAutomatically = true는
    @Modifying 애노테이션의 속성으로, 데이터베이스 변경 작업 후 영속성 컨텍스트를 자동으로 클리어(clear)하는지 여부를 나타냅니다.

⭐️ 참고: 벌크 연산은 영속성 컨텍스트를 무시하고 실행하기 때문에, 영속성 컨텍스트에 있는 엔티티의 상태와 DB에 엔티티 상태가 달라질 수 있다.

권장하는 방안
1. 영속성 컨텍스트에 엔티티가 없는 상태에서 벌크 연산을 먼저 실행한다.
2. 부득이하게 영속성 컨텍스트에 엔티티가 있으면 벌크 연산 직후 영속성 컨텍스트를 초기화 한다.

참고 : 김영한 강의 Spring Data Jpa

profile
개발자꿈나무

0개의 댓글