Spring/JPA

JPA 준영속, 병합

묠니르묘묘 2022. 2. 21. 23:49

 

 

영속 상태는 persist() 메서드 또는 find() 메서드를 사용할 때 1차 캐시에 저장되면서 영속성 컨텍스트가 관리하면서 된다고 했다.

준영속 상태는 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)됐을 때이다.

이러면 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다. (변경 감지, 지연로딩 등)

 

📝 준영속 상태로 만드는 방법

1. em.detach(entity) - 엔티티를 준영속 상태로 전환

1차 캐시부터 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보 제거

detach 실행 전
detach 실행 후

2. em.clear() - 영속성 컨텍스트 초기화

영속성 컨텍스트를 초기화해서 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만든다.

영속성 컨텍스트 초기화 전
영속성 컨텍스트 초기화 후

3. em.close() - 영속성 컨텍스트 종료

영속성 컨텍스트를 종료하여 관리하던 영속 상태 엔티티 모두 준영속 상태가 된다.

영속성 컨텍스트 제거 전
영속성 컨텍스트 제거 후

 

 

 

📝 준영속 상태의 특징

1. 거의 비영속 상태

영속성 컨텍스트가 관리하지 않으므로 영속성 컨텍스트가 제공하는 기능을 쓸 수 없다.

(1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩 등)

2. 식별자 값을 가지고 있다.

한 번 영속 상태였으므로 반드시 식별자 값을 가지고 있다.

3. 지연 로딩을 할 수 없다.

지연 로딩(LAZY LOADING)은 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법이다.

하지만 영속성 컨텍스트가 관리하지 않으므로 쓸 수 없다.

 

 

 

🧐 준영속 상태에서 다시 영속 상태로 어떻게 합치나요?

em.merge() 메서드로 준영속 상태의 엔티티를 받아서 새로운 영속 상태의 엔티티를 반환할 수 있다.

이것을 병합이라고 한다.

준영속 병합 - 수정

1. merge() 실행

2. 파라미터로 넘어온 준영속 엔티티 식별자 값으로 1차 캐시에서 조회한다.

    2-1. 만약 1차 캐시에 없다면 DB에서 조회하여 1차 캐시에 저장한다.

3. 조회한 영속 엔티티(mergeMember)에 member 엔티티의 값을 넣는다.

4. mergeMember를 반환한다.

 

이렇게 병합하고 트랜잭션 커밋을 하면 DB에 mergeMember의 이름은 "치킨"으로 반영되게 된다.

비영속 엔티티도 같은 원리로 사용할 수 있다.

 

 


자바 ORM 표준 JPA 프로그래밍 / 김영한 지음 / 에이콘출판주식회사 출판

자바 ORM 표준 JPA 프로그래밍 - 기본편 / 김영한 / 인프런 강의