Dev/JPA

RS) 준영속 상태

Okdol-Min 2022. 2. 1. 22:18

영속 상태 : JPA 관리하에 들어가는 상태

크게 두가지 경우의 상태가 있는데

  1. em.persist() 하여 영속성 컨텍스트에 1차 캐시에 올라가는 경우
  2. em.find() 를 했는데 1차 캐시에 없는 경우 데이터베이스에 들리고 가져올 때 1차캐시에 넣어주면서 영속상태가 되는 경우

준영속 상태

  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리되는 상태(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

준영속 상태로 만드는 방법

  • em.detach(entity) - 특정 엔티티만 준영속 상태로 전환
try{
    // 영속
    Member member = em.find(Member.class, 150L);
    member.setName("AAAAA");

    // 영속 -> 준영속 상태
    em.detach(member);
    
    tx.commit();
    
/* 실행 결과 
 - 트랜잭션 커밋하기 전에 detach가 되버려서, 준영속 상태로 인해 update 문이 안나감 */
 
Hibernate: 
select
    member0_.id as id1_0_0_,
    member0_.name as name2_0_0_ 
from
    Member member0_ 
where
    member0_.id=?
    */
  • em.clear() - 영속성 컨텍스트를 완전히 초기화
try{
    // 영속
    Member member = em.find(Member.class, 150L);
    member.setName("AAAAA");

    // 영속 -> 준영속 상태
    em.clear(); // 영속성 컨텍스트를 완전히 초기화

    Member member2 = em.find(Member.class, 150L); // 다시 조회

    tx.commit(); // 커밋하는 순간 디비에 날라간다.
    
/* 실행 결과
 - select 쿼리문이 두번 찍힘
 - 트랜잭션 커밋하기전에 영속성 컨텍스트를 완전 초기화 했기 때문에 다시 영속성 컨텍스트에 올리는 작업을 함 */
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
  • em.close() - 영속성 컨텍스트를 종료
    • 엔티티 매니저 자체를 닫아버리기 때문에 영속성 컨텍스트가 종료되고, 준영속 상태가 되버린다.