Skip to content

Latest commit

 

History

History
99 lines (80 loc) · 3.29 KB

2.영속성관리.md

File metadata and controls

99 lines (80 loc) · 3.29 KB

EntityManagerFactory & EntityManager

DB를 하나만 사용하는 애플리케이션은 일반적으로 EntityManagerFactory를 하나만 생성한다.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("hardy");

EntityManagerFactory는 여러 스레드가 동시에 접근해도 안전하므로 스레드 간에 공유해도 되지만, EntityManager는 스레드 간에 절대 공유하면 안된다.

EntityManager는 DB 연결이 필요한 시점까지 커넥션을 얻지 않는다.


영속성 컨텍스트 (PersistenceContext)

  • JPA를 이해하는데 가장 중요한 용어 (Entity를 영구 저장하는 환경이라는 뜻)
  • EntityManager.persist(entity);
  • 영속성 컨텍스트는 논리적 개념 (눈에 보이지 않는다.)
  • EntityManager를 통해 영속성 컨텍스트에 접근한다.

Entity LifeCycle

비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태

Member member = new Member();
member.setId(1L);
member.setName("회원1");

영속(managed): 영속성 컨텍스트에 저장된 상태

Member member = new Member();
member.setId(1L);
member.setName("회원1");

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

em.persist(member);

준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태

em.detach(member);  // 특정 엔티티만 준영속 상태로 전환
또는
em.clear(); // 영속성 컨텍스트 초기화
또는
em.close(); // 영속성 컨텍스트 종료

삭제(removed): 삭제된 상태

em.remove(member);

영속성 컨텍스트의 이점

1차 캐시 & 동일성(identity) 보장
반복 가능한 읽기(REPEATABLE READ) 등급의 트랙잭션 격리 수준을 DB가 아닌 애플리케이션단에서 제공

Member a = em.find(Member.class, 1L);
Member b = em.find(Member.class, 2L);
System.out.println(a == b); // true

트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();

em.persist(a);
em.persist(b);
// 여기까지는 INSERT 쿼리를 DB에 보내지 않는다.

transaction.commit();   // 커밋하는 순간 DB에 쿼리를 보낸다.

변경 감지 (Dirty Checking)
JPA의 기본 전략은 Entity의 모든 필드 업데이트

@DynamicUpdate로 수정된 데이터만 동적으로 UPDATE하는 SQL 생성도 가능

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();

Member a = em.find(Member.class, 1L);
a.setName("Hardy");
a.setAge(30);

// em.update(a); 이런 코드가 없어도 된다.

transaction.commit();
// 1차 캐시를 만들 때 만들어둔 스냅샷과 비교하여 변경된 부분의 UPDATE 쿼리를 수행한다.

지연 로딩 (Lazy Loading)


flush (플러시)

영속성 컨텍스트의 변경 내용을 DB에 반영한다.

  • 변경 감지가 동작하여 영속성 컨텍스트에 있는 모든 Entity를 스냅샷과 비교하고 수정된 Entity를 찾는다. 수정된 Entity는 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.
  • 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송한다.