본문 바로가기

PROGRAMMING/JPA

[JPA] 변경 감지와 병합

웹에서 변경 데이터를 반환받아 변경해야 할 때 보통 객체를 생성해서 값을 세팅하는데

새로 생성한 객체는 id가 세팅되기 때문에 식별자는 존재하지만 영속성 컨텍스트에서는 관리하지않는 준영속 객체다.

 

이 객체는 JPA가 관리하지 않기 때문에 더티체킹(변경감지)가 일어나지 않는데 이러한 객체를 DB에 반영하는 방법으로 

1. 병합(머지)

2. 변경 감지

 

두가지 있다.

 

예를 들어 Book 데이터를 변경할 때

 

병합 동작방식

1. merge()를 실행한다.

2. 파라미터로 넘어온 엔티티의 식별자 값(ID)으로 1차 캐시에서 조회한다. -> 1차 캐시에 없다면 DB에서 조회하고 1차 캐시에 저장한다.

3. 이렇게 조회한 Book 엔티티는 영속상태로 이 엔티티에 파라미터로 넘어온 값들을 다시 세팅한다. (1차 캐시 포함)

4. 이를 반환한다. 

 

merge() 동작 방식

 

변경 감지 동작방식

1. 파라미터로 넘어온 식별자 값으로 엔티티를 조회해온다.

2. 조회된 엔티티는 영속상태로 이 엔티티에 변경을 원하는 값들을 set한다.

3. 트랜젝션이 끝날 때 알아서 반영이 된다.

 

적용 예제 Controller

 

Service

 

 

병합 주의사항&문제점

변경 감지기능을 사용하면 원하는 속성만 선택해 변경할 수 있지만, 병합은 병합시 전체 필드값을 전부 다 업데이트된다.

필드가 null값으로 빠져있는경우 null로 업데이트 된다.

예를 들어 가격은 변경이 불가능 하다는 의미로 setPrice를 제외하고 병합을 실행하면 가격이 null이 되는 불상사가 발생한다.

 

고로 결론은 가능하면 변경감지를 사용해야한다.