728x90
- (JPA)변경 감지와 병합(merge)
- 엔티티를 수정하는 2가지 방법으로 변경 감지(dirty checking)와 병합(merge)이 있습니다.
- 변경 감지 기능 사용
- 영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법입니다.
- 트랜잭션 안에서 엔티티를 다시 조회, 변경할 값 선택 트랜잭션 커밋 시점에 변경 감지(Dirty Checking) 이 동작해서 데이터베이스에 UPDATE SQL 실행합니다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
- 병합 사용
- 준영속 엔티티의 식별자 값으로 영속 엔티티를 조회합니다.
- 영속 엔티티의 값을 준영속 엔티티의 값으로 모두 교체합니다(병합)
- 트랜잭션 커밋 시점에 변경 감지 기능이 동작해서 데이터베이스에 UPDATE SQL이 실행합니다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item mergeItem = em.merge(item);
}
- 주의: 변경 감지 기능을 사용하면 원하는 속성만 선택해서 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경됩니다. 따라서, 병합시 값이 없으면 null 로 업데이트 할 위험도 있습니다(병합은 모든 필드를 교체하므로)
- 최종 권장 코드
- save() 메서드는 식별자 값이 없으면( null ) 새로운 엔티티로 판단해서 영속화(persist)하고 식별자가 있으면 병합하도록 하며, 전부 null값이 채워지는 오류가 발생하지 않으면서 merge메서드를 활용 가능합니다.
@Repository
public class ItemRepository {
@PersistenceContext
EntityManager em;
public void save(Item item) {
if (item.getId() == null) {
em.persist(item);
} else {
em.merge(item);
}
}
}
728x90
'JPA' 카테고리의 다른 글
페치 조인(fetch join) 의 활용 (0) | 2022.02.14 |
---|---|
회원등록 API v1, v2 차이 (0) | 2022.02.14 |
(Querydsl) ON 절을 활용한 조인 (0) | 2022.02.14 |
queryDsl 기본 조인에 대해 (0) | 2022.02.14 |
Q클래스 인스턴스 사용 방법 두가지 (0) | 2022.02.14 |