-
[Spring] 변경 감지와 병합Spring 2021. 11. 14. 20:06
준영속 엔티티
영속성 컨텍스트가 더는 관리하지 않는 엔티티
(ex : 디비를 통해 가져온 객체가 아닌, 임의로 만들어낸 엔티티)
준영속 엔티티를 수정하는 2가지 방법
- 변경 감지 기능 사용
- 병합 사용
변경 감지 기능 사용
@Transactional public void updateItem(Long itemId, Book param) { Item findItem = itemRepository.findOne(itemId); findItem.setName(param.getName()); findItem.setPrice(param.getPrice()); findItem.setStockQuantity(param.getStockQuantity()); }
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법
트랜잭션 안에서 엔티티를 다시 조회, 변경할 값 선택 -> 트랜잭션 커밋 시점에 변경 감지(Dirty Checking)이 동작해서 데이터베이스에 update sql 실행
병합 사용
public Long save(Item item) { if (item.getId() == null) { em.persist(item); } else { em.merge(item); } return item.getId(); }
병합은 준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능이다.
병합 : 기존에 있는 엔티티
병합 동작 방식
1. merge()를 실행한다.
2. 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다.
2-1. 만약 1차 캐시에 엔티티가 없으면 데이터베이스에서 엔티티를 조회하고, 1차 캐시에 저장한다.
3. 조회한 영속 엔티티(mergeMember)에 member엔티티의 값을 채워 넣는다. (member 엔티티의 모든 값을mergeMember에 밀어 넣는다.)
4. 영속 상태인 mergeMember를 반환한다.
병합시 동작 방식을 간단히 정리
1. 준영속 엔티티의 식별자 값으로 영속 엔티티를 조회한다.
2. 영속 엔티티의 값을 준영속 엔티티의 값으로 모두 교체한다.(병합한다.)
3. 트랜잭션 커밋 시점에 변경 감지 기능이 동작해서 데이터베이스에 UPDATE SQL이 실행
> 주의: 변경 감지 기능을 사용하면 원하는 속성만 선택해서 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경된다. 병합시 값이 없으면 null로 업데이트 할 위험도 있다. (병합은 모든 필드를 교체한다.)
출처 : 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 인프런 | 학습 페이지 (inflearn.com)
'Spring' 카테고리의 다른 글
[Spring] 쿼리 N+1 상황을 해결하는 방법 (0) 2021.11.23 [Spring] API를 보낼 때 엔티티 리스트 통째로 보내면 안되는 이유 (0) 2021.11.19 [Spring]test폴더에 yml파일을 따로 두면 좋은 이유 (0) 2021.11.10 [Spring] 양방향 연관관계 세팅시 필요한 연관관계 메소드 (0) 2021.11.09 [Spring] 테이블, 컬럼명 생성 전략 (0) 2021.11.09