[Spring & JPA] 데이터 수정시 변경감지(dirty checking) vs merge
Web/팁

[Spring & JPA] 데이터 수정시 변경감지(dirty checking) vs merge

JPA는 기본적으로 데이터만 바꿔도 변경감지를 통해 트랜젝션 커밋시점에 sql이 나간다.

 

그런데 *준영속 엔티티 일때는 변경감지가 일어나지 않는다!

 

그러면 준영속 엔티티 상태일때는 데이터를 어떻게 변경해야할까?

 

준영속 엔티티의 데이터 변경에는 두가지 방법이 있다.

  • 변경감지기능 사용
  • merge 사용

변경감지기능사용 방법은 트랜잭션이 있는 서비스계층에서 데이터를 수정하는 것이다. 

 

ItemService

...
    @Transactional
    public Item updateItem(Long itemId, String name, int price, int stockQuantity) {
        Item findItem = itemRepository.findOne(itemId);
        findItem.setPrice(price);
        findItem.setName(name);
        findItem.setStockQuantity(stockQuantity);
        return findItem;
    }
...

트랜잭션이 없는 곳에서는 준영속엔티티가 수정되어도 JPA는 알 방법이 없다. 그래서 트랜잭션이 있는 곳에서 값을 불러와 영속 엔티티로 만든 후 변경감지기능을 사용하는 것이다.

 

ItemRepository

merge도 사실 변경감지기능과 동작방식은 같다.

merge는 변경감지기능을 사용하여 모든필드의 데이터를 바꾸는 코드를 em.merge()로 쓸 수 있는 것 뿐이다.

 

하지만 둘에는 차이가 있다.

변경감지는 원하는 값만 바꿀 수 있는데, merge는 모든 필드를 교체해버린다.

 

그래서 실무에서 데이터 변경을 할 때에는 변경감지로 해야한다.

 

 

 

*준영속 엔티티

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

개발상에서는 영속성컨텍스트로 데이터에 한번 삽입되고, 수정이 필요해 다시 그 데이터를 가져왔을때(id.식별자를 이미 가지고 있음) 영속성 엔티티라고 볼 수 있다.