[4] 스프링 부트와 JPA 활용 (6) - 웹계층 개발 2 (변경감지-Dirty Checking / em.merge)
준영속 엔티티 ?
영속성 컨텍스트
가 관리하지 않는 엔티티
임의로 만든 엔티티
: 수정된 값을 저장하기 위해 식별자
는 있지만 관리되지 않는 엔티티
영속화가 취소된 엔티티
: 강제로 영속화
를 취소
한 엔티티
준영속 엔티티
는 수정
이 일어나도 변경 감지(Dirty Checking)
이 일어나지 않음
준영속 엔티티 수정 방법
[ 방법 ]
변경감지(Dirty Checking)
기능 사용
병합(merge)
사용
[ 변경 감지 기능 사용 ]
- 설명 :
Item을 수정
하는 상황
- 로직
Item 수정
을 하기 위해 수정된 값
을 통해 임의로 만든 객체
는 준영속 엔티티
이다
Item
의 식별자인 Id
를 이용해서 한번 조회
를 하면 영속 엔티티
가 된다
영속 엔티티
가 된 상태에서 데이터
를 수정
--> 변경감지(Dirty Checking)
기능이 사용됨
[ 병합(merge) 사용 ]
- 설명 : Item을 수정하는 상황
- 로직
merge()
실행
준영속 엔티티
의 식별자 값
으로 1차 캐시
에서 엔티티를 조회
(1차 캐시
에 없으면 DB에서 조회
함)
- 조회한 객체인
mergeMember
에 member
값을 복사
mergeMember
가 반환
(반환값
이 영속 엔티티
이고, 파라미터로 넣은 엔티티
는 여전히 준영속 상태
)
- 주의
: 변경감지
와 달리 모든 속성
을 복사
하기 때문에 없으면 null
이 들어간다
(모든 필드
를 교체
하므로 비효율
& 위험성
이 있음
--> 실무
에서는 변경감지를 사용
하자)
[ 정리 ]
변경감지
를 사용한 수정
--> 변경하기 원하는 데이터 값
만 가지고 수정
할 수 있음
merge
를 사용한 수정
--> 변경을 원하지 않는 값
들도 모두 가지고 있어야 하니까 자칫 잘못하면 null값이 들어갈수 있다 (위험성)
- 정리
엔티티 수정
을 할 때에는 변경감지
를 사용하도록 로직을 설계!
- 1)
트랜잭션
이 있는 서비스 계층
에 식별자
와 변경할 데이터
를 전달
- 2)
트랜잭션
이 있는 서비스 계층
에서 영속상태의 엔티티
를 조회
하고, 엔티티
의 데이터
를 직접 변경
하자