[JPA] 영속성 컨텍스트 1

이영재·2024년 10월 18일
0

Spring

목록 보기
5/15
post-thumbnail

JPA에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑하기
  • 영속성 컨텍스트

이번엔 영속성 컨텍스트가 뭔지 알아보자

🔎 영속성 관리

JPA를 이해하는데 가장 중요한 키워드 영속성 컨텍스트
"엔티티를 영구 저장하는 환경" 을 말한다.
다음과 같이 영속성 컨텍스트에 접근

EntityManager.persist(entity);

엔티티 매니저는 또 뭐여??
-> 엔티티 매니저란 엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다

  • 엔티티 팩토리 : 엔티티 매니저를 만드는 공장
  • 엔티티 매니저 : 영속성 컨텍스트에 접근

❓왜 직접 엔티티 팩토리에서 엔티티 매니저를 생성할까?

DB를 하나만 사용하는 애플리케이션은 Entity Factory를 하나만 생성한다.
Entity Factory를 생성하는데 많은 비용이 든다.

  • 이제 엔티티 매니저를 계속 생성할 수 있는데, 이때는 비용이 거의 안 든다.

    엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 되지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대 공유하면 안된다.

위 그림을 잘 살펴보면 여러개의 엔티티 매니저가 생성되었을 때 DB연결이 필요한 EntityManager2만 커넥션을 획득한다. EntityManager1 처럼 생성만 하고 커넥션을 얻기 전에는 커넥션은 사용하지 않는다.

추가적으로 Entity Factory를 생성할 때 커넥션 풀을 만들고 사용된다.

🔎 영속성 컨텍스트란?

영속성 컨텍스트란 엔티티를 영구 저장하는 환경 이라는 뜻으로 엔티티 매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.

영속성 컨텍스트는 논리적으로 존재하기 때문에 눈으로 보이지 않고 엔티티 매니저를 생성할 때 하나 만들어진다. 그리고 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있는 것이다.

🔎 엔티티의 생명주기

엔티티에는 4가지 상태가 존재한다

  • 비영속(new/transient)
    영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속(managed)
    영속성 컨텍스트에 관리되는 상태
  • 준영속(detached)
    영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제(removed)
    삭제된 상태

비영속

엔티티 객체를 생성하고 아직 em.persist() 호출하지 않은 상태
영속성 컨텍스트나 데이터베이스와 전혀 관련이 없다.

//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

영속

엔티티 매니저를 통해서 엔티티를 영속성 컨텍스트에 저장했다.
영속 상태라는 것은 영속성 컨텍스트에 의해 관리된다는 뜻이다.

//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername(“회원1);

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

//객체를 저장한 상태(영속)
em.persist(member);

준영속

영속성 컨텍스트가 관리하던 영속 상태의 엔티티를 영속성 컨텍스트가 관리하지 않으면 준영속 상태가 된다.
em.detch() em.close() 를 호출해 영속성 컨텍스트를 닫는다.
또는 em.clear()를 통해서 컨텍스트를 초기화 한다.

em.detach(member);

삭제

엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다.

em.remove(member);

🔎 persist()를 하면 DB에 저장되는 것일까?

다음 코드를 실행 시켰을 때 과연 SQL 쿼리는 어느 시점에서 나갈까?

//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername(“회원1);

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();

em.getTransaction().begin();

System.out.println("===before===")
em.persist(member);
System.out.println("===after===")

tx.commit();

persist 가 엔티티를 영속성 컨텍스트에 저장한다는 뜻이니까 ===before=== 후에 DB에 insert 쿼리가 나가지 않을까??

===before===
===after===
Hibernate: 
    insert 
    into 
        Member 
        (id, username) 
    values 
        (?, ?)

결과는 ===after=== 이후에 DB에 저장하는 insert 쿼리가 나간다. 뭔가 이상하다.
그럼 영속 상태로 만든다는 것은 DB에 바로 저장하는 뜻이 아니다.
중간에 다른 로직이 동작하는 거 같다. 다음 포스팅에서 더 알아보자

0개의 댓글

관련 채용 정보