DEV ℧ Developer Diary

[JPA] 준영속

해당 포스트는 인프런 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 을 듣고 정리한 글입니다.

준영속

영속상태는 persist 뿐만 아니라 find와 같은 엔티티를 가져올 때도 영속상태로 엔티티를 가져온다.

  • 영속 -> 준영속
  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detach)
  • 영속성 컨텍스트가 제공하는 기능을 사용못한다. (더티체킹.. 등등)

준영속 상태로 만드는 방법

  • entityManager.detach(entity) : 특정 엔티티만 준영속 상태로 전환
  • entityManager.clear() 영속성 컨텍스트를 완전히 초기화
  • entityManager.close() 영속성 컨텍스트를 종료

detach

아래의 실행 예시를 살펴보면, entityManager.detach(findMemberA); 를 이용해 준영속 상태로 만들시, 변경감지된 entity에서 UPDATE 쿼리를 만들지 않는다.

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();

entityTransaction.begin();
try {
    Member findMemberA = entityManager.find(Member.class, 102L);
    findMemberA.setName("Modify JAVA");

    log.debug("detach - BEFORE");
    entityManager.detach(findMemberA);
    log.debug("detach - AFTER");

    entityTransaction.commit();
} catch (Exception e) {
    entityTransaction.rollback();
} finally {
    entityManager.close();
}
07:38:39.438 [main] DEBUG org.hibernate.SQL -
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_
    from
        Member member0_
    where
        member0_.id=?
07:38:39.469 [main] DEBUG com.dhaudgkr.jpastart.hellojpa.JpaPersistent - detach - BEFORE
07:38:39.475 [main] DEBUG com.dhaudgkr.jpastart.hellojpa.JpaPersistent - detach - AFTER

clear

동일한 Key의 Entity를 조회해도 entityManager.clear() 이후 해당 Entity에 대한 1차캐시가 날라가 다시 SELECT SQL을 조회한 것을 확인할 수 있다.

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();

entityTransaction.begin();
try {
    Member findMemberA = entityManager.find(Member.class, 102L);
    log.debug("clear - BEFORE");
    entityManager.clear();
    log.debug("clear - AFTER");
    Member findMemberB = entityManager.find(Member.class, 102L);

    entityTransaction.commit();
} catch (Exception e) {
    entityTransaction.rollback();
} finally {
    entityManager.close();
}
07:43:40.910 [main] DEBUG org.hibernate.SQL -
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_
    from
        Member member0_
    where
        member0_.id=?
07:43:40.943 [main] DEBUG com.dhaudgkr.jpastart.hellojpa.JpaPersistent - clear - BEFORE
07:43:40.945 [main] DEBUG com.dhaudgkr.jpastart.hellojpa.JpaPersistent - clear - AFTER
07:43:40.945 [main] DEBUG org.hibernate.SQL -
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_
    from
        Member member0_
    where
        member0_.id=?

close

해당 EntityManager에 대한 커넥션을 닫아버리기 때문에 모든 영속성 컨텍스트에 올라간 Entity를 해제한다.