[JPA] 변경 감지와 병합 (merge)

hi·2022년 10월 27일

살려줘요


영속 상태로 관리되는 엔티티의 값이 변경되면, 트랜잭션 커밋 시점에 변경된 내용이 DB에 반영된다

준영속 엔티티란?

: 영속성 컨텍스트가 더는 관리하지 않는 엔티티

  • 영속성 컨텍스트에 저장되었다가 분리된 상태
    영속성 컨텍스트가 제공하는 기능 사용 불가

  • 새로운 객체여도 이미 DB에 저장되었던 기존의 식별자를 갖고 있다면 준영속 엔티티

문제

JPA가 관리하지 않음 -> 값이 변경되어도 DB 업데이트 X


준영속 엔티티를 수정하는 방법

1. 변경 감지 (Dirty Checking)

  • 트랜잭션 안에서 준영속 엔티티의 식별자 값으로 영속 상태 엔티티를 조회, 값 변경
    👉 트랜잭션 커밋 시점에 변경 감지
  • 원하는 속성만 선택하여 변경 가능

2. 병합 (Merge)

: 준영속 상태의 엔티티를 영속 상태로 변경

em.merge(entity);

em.merge(entity); 실행
-> 준영속 엔티티의 식별자 값으로 1차 캐시 또는 DB에서 영속 엔티티 조회
-> 영속 엔티티의 모든 값을 준영속 엔티티의 값으로 교체(병합)
-> 트랜잭션 커밋 시점에 변경 감지
-> 영속 상태의 엔티티 반환

  • 모든 필드를 교체
  • 병합시 값이 없으면 null로 업데이트 됨
  • 준영속 엔티티가 영속 상태로 변하는 것이 아니라,
    병합된 영속 엔티티가 반환되는 것

엔티티 변경시에는 항상 변경 감지 사용

  • 컨트롤러에서 어설프게 엔티티를 생성하지 않음
    (엔티티를 파라미터로 사용하지 않고 필요한 데이터만 전달)

  • 업데이트할 파라미터가 많다면 DTO 사용

더 나은 설계

  • 변경시 set 사용 X
  • 의미있는 메서드 생성 , 변경지점을 엔티티로

0개의 댓글