[JPA] Dirty Checking 과 merge

박재빈·2024년 11월 18일
0

JPA를 통해서 update를 하는 방법에는 두가지 방법이 있습니다.

  • dirty checking : 변경 감지
  • merge : 병합

Dirty Checking이란?

Dirty Checking은 JPA의 영속성 컨텍스트(Persistence Context)에서 관리되는 엔티티의 변경 사항을 자동으로 감지하여 데이터베이스에 반영하는 기능입니다.

작동 원리

  • JPA는 영속성 컨텍스트에 저장된 엔티티의 스냅샷을 유지합니다.
  • 트랜잭션이 종료되기 전, 스냅샷과 현재 엔티티 상태를 비교합니다.
  • 변경 사항이 있다면, 자동으로 UPDATE쿼리를 생성하여 데이터베이스에 반영합니다.

예시 코드

@Transactional
public void updateEntity(Long id, String newName) {
    Member member = entityManager.find(Member.class, id); // 영속성 컨텍스트에 엔티티 로드
    member.setName(newName); // 엔티티 상태 변경
}

Merge란?

Merge는 영속성 컨텍스트에서 관리되지 않는 준영속 엔티티를 다시 영속 상태로 만드는 데 사용됩니다.

준영속 엔티티
준영속 엔티티는 한때 영속성 컨텍스트에서 관리되었으나, 더 이상 관리되지 않는 상태의 엔티티를 말합니다.

동작 원리

  1. 엔티티를 영속성 컨텍스트에서 찾기

    • merge가 호출되면 JPA는 해당 엔티티의 식별자(PK)를 이용해 영속성 컨텍스트에서 동일한 ID를 가진 엔티티를 조회합니다.
    • 만약 해당 엔티티가 영속성 컨텍스트에 존재하지 않으면 데이터베이스에서 엔티티를 로드하여 영속성 컨텍스트에 추가합니다.
  2. 값 복사(병합)

    • 준영속 상태의 엔티티와 영속성 컨텍스트의 엔티티 간에 모든 필드 값을 복사합니다.
  3. 변경 사항 반영

    • 영속 상태의 엔티티는 트랜잭션이 커밋되거나 플러시될 때 데이터베이스에 변경 사항이 반영됩니다.

예시 코드

@Transactional
public void mergeEntity(Member member) {
    Member mergedMember = entityManager.merge(member); 
}

어떤 방식을 사용하는 것이 좋을까?

Dirty Checking의 경우 원하는 속성만 선택해서 변경할 수 있지만 Merge를 사용하면 모든 속성이 변경됩니다. 즉 Merge를 사용할 때 값이 없으면 null로 업데이트 할 위험도 있습니다.

따라서 권장되는 엔티티 변경 방법으로는 Dirty Checking을 사용하는 것이 좋습니다.

0개의 댓글