코딩무비

[JPA] 영속성 컨텍스트(Persistence Context)

by 코딩무비

JPA

반응형

JPA을 사용하면서 영속선 컨텍스트에 대한 개념이 명확하지 않아 정리하고자 합니다.

영속성 컨텍스트를 알기 전에 영속이란 단어를 몰라서 국어사전에 검색해 봤습니다.

 

영속이 뭐지?

영원히 계속되는 것이라 한다. 개발자 영속

 

 

영속성 컨텍스트(Persistence Context)란?

  • EntityManager엔티티영구 저장하는 환경

영속성 컨텍스트에서는 Key(@Id), Value(Entity) 값으로 되어 있다.

⇒ 내부구조는 HashMap으로 되어있다는 것을 알 수 있다.

 

 

 

EntityManager은 영속성 컨텍스트에서 Entity을 찾는 동작과정은 어떻게 될까?

⇒ Key을 통해 영속성 컨텍스트에 해당 Entity가 없으면 DB에 select 쿼리를 날려서 데이터를 가져온다.

영속성 컨텍스트에 해당 Entity가 있는 경우

영속성 컨텍스트에서 id 값을 이용하여 Entity을 찾았을 때는 DB을 거치지 않고 바로 리턴해준다.

 

 

영속성 컨텍스트에 해당 Entity가 없는 경우

영속성 컨텍스트에서 id 값을 이용하여 Entity을 찾지 못하였을 때 DB에 SELECT 쿼리를 날려 데이터를 가져와 영속성 콘텍스트에 저장한 후 리턴해준다.

 

 

 

우리는 Entity에서

@Id어노테이션을 이용하여 해당 필드로 Entity식별하도록 설정할 수 있다.

 

Member Entity

@Entity
@Data
@NoArgsConstructor
public class Member {
    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private int age;

    public Member(Long id, String username, int age) {
        this.id = id;
        this.username = username;
        this.age = age;
    }

    public Member(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

Entity에 @Data 어노테이션을 붙이는 것은 좋지 않다. 지금은 실습을 위해 간단하게 표현하기 위하여 사용함

 

 

엔티티의 생명주기

  • 비영속(trasient)
    • 영속성 컨텍스트와 관계가 없는 새로운 상태
Member jinho1 = new Member("jinho1", 27);
Member jinho2 = new Member("jinho2", 28);
Member jinho3 = new Member("jinho3", 29);
  • 영속
    • 영속성 컨텍스트에 저장된 상태이다.
    • EntityManager가 해당 엔티티를 관리한다.
    • em.persist(entity)을 이용하여 영속상태로 만들 수 있다.
  • 준영속
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
    • em.detach(entity)을 이용하여 준영속상태로 만들 수 있다.
  • 삭제
    • 영속성 컨텍스트에 삭제된 상태
    • em.remove(entity)을 이용하여 영속성컨텍스트에서 삭제할 수 있다.
    • 삭제 쿼리는 영속성 컨텍스트에 쓰기지연저장소에 저장된다.

 

 

플러시(Flush)

  • 영속성 컨텍스트에 남아있는 쓰기 지연 SQL문을 DB에 반영

 

영속성 컨텍스트의 장점

1. 1차 캐시

2. 변경 감지(Dirty Checking)

3. 동일성 보장

 

실습 코드

EntityManagerFactory emf = Persistence.createEntityManagerFactory("practice");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();

try {
    // 트랜잭션 시작
    tx.begin();
    // 비영속
    Member jinho1 = new Member("jinho1", 27);
    Member jinho2 = new Member("jinho2", 28);
    Member jinho3 = new Member("jinho3", 29);

    // 영속성 컨텍스트에 영속
    em.persist(jinho1);
    em.persist(jinho2);
    em.persist(jinho3);

    // 영속성 컨텍스트의 1차캐시에서 찾아옴 => GET
    Member user = em.find(Member.class, 2L);
    System.out.println(user.getUsername());

    // 트랜잭션 commit -> DB에 반영
    tx.commit();

} catch (Exception e) {
    // 트랜잭션 롤백
    tx.rollback();
} finally {
    em.close();
}
반응형

블로그의 정보

코딩무비

코딩무비

활동하기