본문 바로가기
개발/Spring

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

by 윤호 2021. 9. 6.

변경 감지와 병합

  • 변경 감지 - 더티체킹 (엔티티의 값만 바꿔도 JPA가 알아서 update 쿼리)
    • @Transactional 안에 this.setStatus(oderStatus.CANCEL);만 해도 자동으로 update 해줌
    • 영속성 엔티티들에 적영됨.
    • findById로 찾은 엔티티는 영속성 컨텍스트
      • Book book = itemRepository.findById(param.getId());
      • 디비에서 참조했기 때문
  • 준영속 엔티티
    • 영속성 컨테스트가 더이상 관리하지 않는 엔티티
    • 엔티티 속성을 바꿔도 변경 감지를 통한 업데이트가 되지 않음.
    • 엔티티를 그냥 Id로 접근한경우
      • book.setId(form.getId())
  • 병합 em.merge
    • 디비에서 id 조회를 하고 필드를 모두 바꿔치기함.
    • 준영속 상태를 영속성으로 변경해줌
    • 주의점 (병합은 최대한 사용하지 않을 것. 변경감지를 사용한다.)
      • 변경감지를 사용하면 원하는 속성만 선택해서 변경하지만
      • 병합시에는 모든 필드를 교체함. -> 필드값에 null이 들어갈 위험이 있음
  • 결론
    • 병합이 아닌 변경감지를 사용하도록 할 것.
    • controller에서 어설프게 엔티티를 생성하지 말 것
    • 트랜잭션이 있는 서비스 계층에 식별자(id)와 변경할 데이터를 명확하게 전달할 것(파라미터 or dto)
    • 트랜잭셔이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 데이터를 직접 변경할 것
    • 트랜잭션 커밋 시점에 변경감지가 실행됨.
    • 추가로 서비스계층에서도 엔티티의 set메소드를 쓰지 말고 엔티티의 메서드를 생성해서 사용할 것

댓글