준영속
작성일
준영속 상태란
영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
된 것을 말한다. 준영속 상태의 엔티티는 영속성 컨텍스트에서 분리되었기 때문에 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다. (Dirty Checking 등)
참고 영속 상태가 되는 경우
- em.persist() 할 경우
- em.find()를 했는데 1차 캐시에 데이터가 없어 DB에서 조회했을 때
준영속 상태로 만드는 방법
- em.detach(entity): 특정 엔티티만 준영속 상태로 전환한다.
- em.clear(): 영속성 컨텍스트를 완전히 초기화한다.
- em.close(): 영속성 컨텍스트를 종료한다.
엔티티를 준영속 상태로 전환
특정 엔티티만 준영속 상태로 전환한다. em.detach(entity)를 하는 순간 영속성 컨텍스트에게 더는 해당 엔티티를 관리하지 말라는 의미이다. 이 메소드를 호출하면 1차 캐시부터 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보가 제거된다.
// 영속 상태
Member member = em.find(Member.class, 200L);
member.setName("AAAA");
// 준영속 상태로 변경
em.detach(member);
tx.commit();
영속성 컨텍스트 초기화
em.detach()는 특정 엔티티 하나를 준영속 상태로 만들고, em.clear()
는 영속성 컨텍스트를 초기화해서 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만든다.
// 영속 상태
Member member = em.find(Member.class, 200L);
// 영속성 컨텍스트 초기화, 1차 캐시도 초기화 됨
em.clear();
// 1차 캐시에 없으니 다시 select문 실행
Member member2 = em.find(Member.class, 200L);
tx.commit();
영속성 컨텍스트 종료
em.close()를 통해 영속성 컨텍스트를 종료하면 해당 영속성 컨텍스트가 관리하던 영속 상태의 엔티티가 모두 준영속 상태가 된다.
참고 영속성 컨텍스트 초기화 vs 영속성 컨텍스트 종료 영속성 컨텍스트 초기화와 종료의 차이점은 초기화는 1차 캐시, 쓰기 지연 SQL은 남아있고 데이터만 지워지는 것이고 종료는 아예 1차 캐시, 쓰기 지연 SQL까지 없어지는 것이다.
준영속 상태의 특징
- 비영속 상태에 가깝다.
- 영속성 컨텍스트에서 관리하지 않으므로 영속성 컨텍스트가 제공하는 어떠한 기능도 사용할 수 없다.
- 식별자 값을 가지고 있다.
- 준영속 상태는 이미 한 번 영속 상태였으므로 식별자 값을 가지고 있다.
- 지연 로딩을 할 수 없다.
- 지연 로딩은 객체를 상속받아 프록시 객체로 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법이다.
- 하지만, 준영속 상태에서는 영속성 컨텍스트가 관리하지 않으므로 지연 로딩 시 문제가 발생한다.