728x90
1. 준영속
1.1 준영속 상태란?
영속 상태의 엔티티가 영속성 컨텍스트에서 분리된 것을 준영속 상태라고 한다.
준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
1.2 준영속 엔티티란 ?
준영속 상태에 있는 엔티티로 영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다.
- 데이터베이스에 한번 저장된 엔티티
- 데이터베이스에 한번 저장되어 식별자(id)가 존재하는 객체
이러한 준영속 엔티티들은 JPA가 관리하지 않기 때문에, 객체를 수정해도 DB에 Update가 일어나지 않는다.
준영속 엔티티가 영속 엔티티와 뭐가 다른지 모르겠다면 아래 블로그 글을 확인해 보자
[spring] JPA 영속성 컨텍스트가 뭔데?
1. 영속성 컨텍스트란? 엔티티를 영구 저장하는 환경 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할 엔티티 매니저를 통해 엔티티를 저장하거나 조회
wwan13.tistory.com
2. 준영속 엔티티 수정 방법
준영속 엔티티를 수정하는 방법에는 두 가지 방법이 있다.
- 변경 감지 기능
- 병합 사용
2.1. 변경 감지 기능 사용 (Dirty Checking)
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법.
service 계층에 메서드를 추가한다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
- 준영속 상태로 넘어온 itemParam 의 id를 이용해 em.find()를 호출해 영속상태로 만들어준다.
- 영속상태의 item을 수정해 변경 감지 기능을 이용한다.
- 이렇게 영속상태의 데이터를 수정하면 커밋 시점에 내부적으로 flush가 발생해 Dirty Checking (변경 감지) 가 일어난다.
- 즉, 변경 감지 기능은 준영속 엔티티의 id로 영속 엔티티를 불러와 수정하는 것이다.
2.2 병합 사용 (Merge)
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item mergeItem = em.merge(itemParam);
}
- 다른 과정 없이 merge()를 호출하는 것 만으로 수정이 가능하다.
merge(itemParam) 과정 설명
1. merge(itemParam) 실행
2. 파라미터로 넘어온 준영속 엔티티의 식별자로 1차 캐시 조회
2-1. 만약 1차 캐시에 없다면 DB 조회 후 1차 캐시에 저장
3. 조회한 영속 엔티티(item)을 준영속 엔티티 (itemParam) 값으로 수정한다.
4. 영속상태인 mergeItem을 반환한다.
* 주의 : 변경 감지 기능을 사용하면 원하는 속성만 선택애 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경된다. 병합시 값이 없으면 NULL 로 업데이트 될 위험도 있다.
실무에서는 업데이트 기능이 매우 제한적 이라고 한다. 하지만 병합은 모든 필드를 변경해버리고, 데이터가 없으면 null로 업데이트 해버린다. 이러한 문제를 해결하려면 변경 폼 화면에서 모든 데이터를 항상 유지해야 하지만, 보통 변경 가능한 데이터만 노출하기 때문에, 병합을 사용하는 것이 오리혀 번거롭다.
3. 결론
엔티티를 변경할 떄는 항상 변경 감지를 사용해라.
- 컨트롤러에서 어설프게 엔티티를 생성하지 마라
- 트랜잭션이 있는 서비스 계층에 식별자와 변경할 데이터를 명확하게 전달해라.
- 트랜잭션이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 엔티티의 데이터를 직접 변경해라.
- 트랜잭션 커밋 시점에 변경 감지가 실행된다.
참고자료
https://www.inflearn.com/course/스프링부트-JPA-API개발-성능최적화/dashboard
wwan13 - Overview
😜. wwan13 has 32 repositories available. Follow their code on GitHub.
github.com
728x90