웹에서 변경 데이터를 반환받아 변경해야 할 때 보통 객체를 생성해서 값을 세팅하는데
새로 생성한 객체는 id가 세팅되기 때문에 식별자는 존재하지만 영속성 컨텍스트에서는 관리하지않는 준영속 객체다.
이 객체는 JPA가 관리하지 않기 때문에 더티체킹(변경감지)가 일어나지 않는데 이러한 객체를 DB에 반영하는 방법으로
1. 병합(머지)
2. 변경 감지
두가지 있다.
예를 들어 Book 데이터를 변경할 때
병합 동작방식
1. merge()를 실행한다.
2. 파라미터로 넘어온 엔티티의 식별자 값(ID)으로 1차 캐시에서 조회한다. -> 1차 캐시에 없다면 DB에서 조회하고 1차 캐시에 저장한다.
3. 이렇게 조회한 Book 엔티티는 영속상태로 이 엔티티에 파라미터로 넘어온 값들을 다시 세팅한다. (1차 캐시 포함)
4. 이를 반환한다.

변경 감지 동작방식
1. 파라미터로 넘어온 식별자 값으로 엔티티를 조회해온다.
2. 조회된 엔티티는 영속상태로 이 엔티티에 변경을 원하는 값들을 set한다.
3. 트랜젝션이 끝날 때 알아서 반영이 된다.
적용 예제 Controller
Service
병합 주의사항&문제점
변경 감지기능을 사용하면 원하는 속성만 선택해 변경할 수 있지만, 병합은 병합시 전체 필드값을 전부 다 업데이트된다.
필드가 null값으로 빠져있는경우 null로 업데이트 된다.
예를 들어 가격은 변경이 불가능 하다는 의미로 setPrice를 제외하고 병합을 실행하면 가격이 null이 되는 불상사가 발생한다.
고로 결론은 가능하면 변경감지를 사용해야한다.
'PROGRAMMING > JPA' 카테고리의 다른 글
| [QueryDSL] QueryDSL 프로젝트에 세팅하기 (0) | 2022.01.06 |
|---|---|
| [DataJPA] 페이징 사이즈 옵션 주기 (0) | 2022.01.04 |
| [JPQL] 묵시적&명시적 조인 (0) | 2021.12.05 |
| [JPQL] Enum 타입 파라미터 바인딩 (0) | 2021.12.04 |
| [JPQL] 페이징 처리 (0) | 2021.12.03 |