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

Hocaron·2021년 12월 27일
0

Spring

목록 보기
13/44

준영속 엔티티?

  • 영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다.
  • DB에 한번 갔다온 친구🙋‍♀️
  • 임의로 만들어낸 엔티티도 기존 식별자를 가지고 있으면 준영속 엔티티로 볼 수 있다.

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

변경 감지( ditry checking ) 기능 사용

@Transactional
    public Item updateItem(Long itemId, Book bookParam) {
        Item item = itemRepository.findOne(itemId);
        item.setPrice(bookParam.getPrice());
        item.setStockQuantity(bookParam.getStockQuantity());
        ...
        return item;
    }
  • 영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법
    트랜잭션 안에서 엔티티를 다시 조회, 변경할 값 선택 트랜잭션 커밋 시점에 변경 감지(Dirty Checking)이 동작해서 데이터베이스에 UPDATE SQL 실행

병합( merge ) 사용

@Transactional
void update(Item item) { 
//item: 파리미터로 넘어온 준영속 상태의 엔티티
 Item mergeItem = em.merge(item);
}
  • 병합은 준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능

주의: 변경 감지 기능을 사용하면 원하는 속성만 선택해서 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경된다. 병합시 값이 없으면 null 로 업데이트 할 위험도 있다. (병합은 모든 필드를 교체한다.)

가장 좋은 해결 방법

엔티티를 변경할 때는 항상 변경 감지를 사용하자

  • 컨트롤러에서 어설프게 엔티티를 생성하지 말자.
  • 트랜잭션이 있는 서비스 계층에 식별자( id )와 변경할 데이터를 명확하게 전달하자.(파라미터 or dto).
  • 트랜잭션이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 엔티티의 - 데이터를 직접 변경하자.
  • 트랜잭션 커밋 시점에 변경 감지가 실행된다.
  • setter없이 바로 추적할 수 있는 메서드 만들자.(유지보수를 위해서)
profile
기록을 통한 성장을

0개의 댓글