JPA에서 준영속 엔티티는 영속성 컨텍스트에서 더 이상 관리하지 않는 엔티티를 뜻한다.
이런 준영속 엔티티를 변경하는 방법은 JPA에서 2가지가 있는데,
변경감지와 병합이 있다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한 다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다. }
데이터베이스에서 내가 찾고자 하는 엔티티를 조회해서, 해당 엔티티를 수정하고 트랜잭션 커밋 시점에 JPA가 스냅샷을 통해서 변경감지(더티체킹)를 통해서 엔티티의 값을 수정해주는 것이다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item mergeItem = em.merge(itemParam);
}
병합의 동작 방식은 이렇다
- merge()를 실행한다.
- 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다.
2-1. 만약 1차 캐시에 값이 없다면 데이터베이스에서 엔티티를 조회하고 1차 캐시에 저장한다.- 조회한 영속 엔티티에 파라미터로 넘어온 엔티티의 값을 채워 넣는다.
- 영속상태의 엔티티를 반환한다.
주의 사항
변경감지는 내가 원하는 값만 선택해서 값을 변경할 수 있지만, 병합은 내가 변경하지 않은 모든 값들은 null로 업데이트가 되기에 주의 사항이 필요하다.
그래서 병합보단 변경감지를 사용하는 것이 더 좋다.