3.6 준영속
영속성 컨텍스트카 관리하는 영속상태의 엔티티가 영속성 컨텍스트에서 분리(detach)된 것을 준영속 상태라 한다. 따라서 준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.
1. em.detach(entity) : 특정 엔티티만 준영속 상태로 전환한다.
2. em.clear() : 영속성 컨텍스트를 완전히 초기화한다.
3. em..close() : 영속성 컨텍스트를 종료한다.
3.6.1 엔티티를 준영속 상태로 전환: detach()
em.detach() 메소드는 특정 엔티티를 준영속 상태로 만든다.
영속성 컨텍스트에서 해당 엔티티에 대한 모든 정보를 삭제한다. 심지어 쓰기 지연 SQL 저장소의 INSERT SQL도 제거되어서 데이터베이스에 저장되지도 않는다. -> 영속성 컨텍스트로부터 분리된 상태이다.
3.6.2 영속성 컨텍스트 초기화
em.detach()다 특정 엔티티 하나를 준영속 상태로 만들었다면 em.clear()는 영속성 컨텍스트를 초기화해서 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만든다.
//엔티티 조회, 영속 상태
Member member = em.find(Member.class, "memberA");
em.clear(); //영속성 컨텍스트 초기화
//준영속 상태
member.setUsername("changeName");
3.6.3 영속성 컨텍스트 종료: close()
영속성 컨텍스트를 종료하면 해당 영속성 컨텍스트가 관리하던 영속 상태의 엔티티가 모두 준영속 상태가 된다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); //트랜잭션 시작
Member memberA = em.find(Member.class, "memberA");
Member memberB = em.find(Member.class, "memberB");
transaction.commit(); //커밋
em.close();
3.6.4 준영속 상태의 특징
- 비영속 상태에 가깝다.
영속성 컨텍스트가 관리하지 않으므로 1차캐시, 쓰기지연, 변경감지, 지연 로딩을 포함한 영속성 컨텍스트가 제공하는 어떠한 기능도 동자하지 않는다.
- 식별자값을 가지고 있다.
비영속 상태는 식별자 값이 없을 수도 있지만 준영속 상태는 이미 한번 영속상태였으므로 반드시 식별자 값을 가지고 있다.
- 지연로딩(Lazy loading)을 할 수 없다.
지연로딩은 실제 객체 대신 프록시 객체를 로딩해 두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법 -> 준영속 상태는 영속성 컨텍스트가 더는 관리하지 않으므로 문제가 발생한다.
3.6.5 병합: merge()
준영속 상태의 엔티티를 다시 영속상태로 변경한다. merge() 메소드는 준영속 상태의 엔티티를 받아서 그 정보로 새로운 영속 샅태의 엔티티를 반환한다.
1. merge()를 실행한다.
2. 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다.
3. 만약 1차캐시에 엔티티가 없다면 DB에서 엔티티를 조회하고 1차캐시에 저장한다.
4. 조회한 영속 엔티티에 member 엔티티의 값을 채워 넣는다.
5. mergeMember를 반환한다.
merge()는 파라미터로 넘어온 준영속 엔티티를 사용해서 새롭게 병합된 영속 상태의 엔티티를 반환한다. 파라미터로 넘어온 엔티티는 병합 후에도 준영속 상태로 남아있다.
비영속 병합병합은 비영속 엔티티도 영속 상태로 만들 수 있다.병합은 파라미터로 넘어온 엔티티의 식별자 값으로 영속성 컨텍스트를 조회하고 찾는 엔티티가 없으면 데이터베이스에서 조회한다. 만약 DB에서도 발견하지 못하면 새로운 엔티티를 생성해서 병합한다.
병합은 준영속, 비영속을 신경쓰지 않는다. 식별자 값으로 조회할 수 있으면 새로 생성해서 병합된다. 따라서 병합은 save or update 기능을 수행한다.