Home [JPA] JPA 기본 3
Post
Cancel

[JPA] JPA 기본 3

JPA 기본 3

영속성 컨텍스트

  • JPA를 이해하는데 가장 중요한 용어
  • 엔티티를 영구 저장하는 환경이라는 뜻이다.
  • 영속성 컨텍스트는 논리적인 개념이다.
  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근 가능하다.

J2SE 환경

  • EntityManager와 PersistenceContext가 1대 1로 매핑된다.

Entity의 생명주기

비영속 (new/transient)

  • PersistenceContext와 전혀 관계 없다.
  • 새로운 상태다.
1
2
3
// JPA와는 전혀 연관 관계가 없는 상태다.
Member member = new Member();
member.setId("memberA");

영속 (managed)

  • PersistenceContext에 관리되는 상태다.
1
entityManager.persist(member); // 영속성 컨텍스트가 관라하게 된다. 아직 DB에 저장되지는 않은 상태다. (차후 저장)

준영속 (detached)

  • PersistenceContext에 저장되었다가 분리된 상태다.
1
entityManager.detach(member); // 영속성 컨텍스트에서 member를 분리한다.

삭제 (removed)

  • 삭제된 상태
1
entityManager.remove(member); // member 객체를 DB에서 지우겠다는 요청을 보낸다.

영속성 컨텍스트의 이점

1차 캐시

1
2
3
4
5
6
7
8
9
10
11
12
13
// 엔티티를 생성한 상태 - 비영속
Member m = new Member();
m.setId("m1");
m.setName("merry");

// 영속 상태로 전환, 1차 캐시에 저장된다.
em.persist(m);

// 조회 - 1차 캐시에서 조회한다. (즉, 조회하는 SQL을 날리지 않는다는 것이다.)
Member findedMember1 = em.find(Member.class, "m1");

// DB에서 조회, 1차 캐시에 없으므로 조회용 SQL을 날린다.
Member findedMember2 = em.find(Member.class, "m2");

동일성(identity) 보장

1
2
3
4
Member a = em.find(Member.class, "m1");
Member b = em.find(Member.class, "m1");

System.out.println(a == b); // true, 1차 캐시를 통해 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 애플리케이션 차원에서 제공한다.

트랜잭션을 지원하는 쓰기 지연

1
2
3
4
5
6
7
8
9
EmtityManager em = emf.createEntiryManager();
EntityTransaction transaction = em.getTransaction();

transaction.begin(); // 트랜잭션 시작

em.persist(A); // 쓰기 지연 SQL 저장소에 적재, 1차 캐시에 저장
em.persist(B); // 쓰기 지연 SQL 저장소에 적재, 1차 캐시에 저장

transaction.commit(); // 트랜잭션 커밋, 쓰기 지연 SQL 저장소에 적재된 SQL을 flush 하여 DB에 INSERT SQL을 날리게 된다.
  • 쓰기 지연을 통해 버퍼링을 사용할 수 있게 된다.

  • hibernate batch 옵션을 통해 batch size 조절 가능하고, 이 사이즈만큼 SQL을 모아서 커밋 시 SQL을 날리는 것이 가능해진다.

변경 감지 (Dirty Checking)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
EmtityManager em = emf.createEntiryManager();
EntityTransaction transaction = em.getTransaction();

transaction.begin(); // 트랜잭션 시작

// 영속 엔티티 조회
Member m = em.find(Member.class, "m1");

// 영속 엔티티 데이터 수정
m.setName("kim");

// em.update(m); ??????? 이런 업데이트 명령 코드가 없어도 변경이 수행된다.

transaction.commit(); 
  • JPA는 일단 값이 변경되면 UPDATE 쿼리가 날라간다고 생각하면 된다.

플러시

  • 변경을 감지하여 쓰기 지연 SQL 저장소에 등록된 쿼리를 데이터베이스에 전송한다.
  • 플러시하는 방법
    • 직접 호출 : em.flush()
    • 자동 호출
      • 트랜잭션 커밋
      • JPQL 쿼리 실행 : 예를 들어 SELECT 쿼리를 날렸을 때, 이전에 추가한 객체의 반영을 위해 이렇게 구성됨.
  • 플러시를 한다고 1차 캐시가 다 날라가는 것은 아니다. 쓰기 지연 SQL 저장소에 적재되어 있는 쿼리만 DB에 반영한다.
    • 즉, 영속성 컨텍스트를 비우지 않고, 변경 내용만 동기화하는 것이다.

준영속 상태

  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리된(detached) 상태로 영속성 컨텍스트가 제공하는 기능 사용이 불가하다.
  • 상태 변환 방법
    • em.detach(entity) : 엔티티를 준영속 상태로 전환
    • em.clear() : 영속성 컨텍스트를 완전히 초기화
    • em.close() : 영속성 컨텍스트를 종료
This post is licensed under younghwani by the author.

[JPA] JPA 기본 2

[JPA] JPA 기본 4

Comments powered by Disqus.