영속성 컨텍스트

2024. 6. 19. 22:01TIL

✔오늘 배운 중요한 🔑 point

  • 영속성= 지속성 
  • 영속성 컨텍스트란 데이터베이스와 자바 객체 사이의 중간 관리자 역할
  • JPQL은 1차캐시를 거치지 않고 바로 데이터베이스를 조회하기 때문에 JPQL 실행전에 Flush()가 실행이 된다
  • merge함수를 사용한다는것은 비영속 엔티티를 영속엔티티로 변환 시키는것이 아니고 비영속 엔티티를 복사해서 영속 엔티티로 새로 생성한다는 것이다

🎯 오늘 배운 내용

 

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

 

영속성 컨텍스트란?

JPA 영속성 컨텍스트는 JPA 에서 제공하는 논리적인 구조로 영속 상태의 Entity 들을 관리하기 위한 목적으로 사용된다

 

 

영속성 컨텍스트가 무엇을 하는가?

 

 

  • 엔티티의 생명 주기 관리: 엔티티 객체가 생성, 읽기, 수정, 삭제되는 과정을 추적.
  • 변경 감지: 영속성 컨텍스트에 있는 엔티티 객체의 변경 사항을 감지하고, 트랜잭션이 커밋될 때 이를 데이터베이스에 반영.
  • 캐싱: 한 번 로드된 엔티티 객체를 영속성 컨텍스트 내에 캐시로 저장하여, 동일한 트랜잭션 내에서 다시 로드할 때 데이터베이스 접근을 최소화.
  • 지연 로딩(Lazy Loading): 필요할 때만 데이터를 불러와서 성능을 최적화.
  • 동일성 보장: 같은 영속성 컨텍스트 내에서는 같은 엔티티 객체에 대해 동일한 인스턴스를 반환하여, 객체의 일관성을 유지.

 

 

영속성 컨텍스트가 지원하는 기능

 

  • 1차캐시
    • 우리가 흔히 알고있는 캐시와 비슷하며 @Transactional과 생명주기가 동일함
  • Entity 동일성 보장
    • 동일한 트랜잭션 내에서 동일한 엔티티를 요청하면 1차 캐시에서 동일한 객체 인스턴스를 반환
      더보기
      EntityManager em = entityManagerFactory.createEntityManager();
      em.getTransaction().begin();

      // 첫 번째 조회 - 데이터베이스에서 조회 후 1차 캐시에 저장
      User user1 = em.find(User.class, 1L);

      // user1 객체의 속성 변경
      user1.setName("John Doe");

      // 두 번째 조회 - 1차 캐시에서 조회 (변경된 내용 포함)
      User user2 = em.find(User.class, 1L);

      // user1과 user2는 동일한 객체를 참조
      assert user1 == user2;

      em.getTransaction().commit();
      em.close();
  • 쓰기지연
    • Entity 에 대한 변경사항을 깃허브에서 여러 커밋을 모아서 한번에 push하는 것처럼  flush() 가 호출되는 시점에 한번에 실행한다. 
  • 변경감지(Dirty Checking)
    • JPA가 엔티티 객체의 상태 변화를 자동으로 감지하고, 데이터베이스에 반영하는 기능으로, 이를 통해 개발자가 직접 SQL 쿼리를 작성할 필요 없이 데이터베이스와 객체 간의 동기화를 쉽게 할 수 있음

 

Flush란?

쓰기지연 SQL 저장소에 쌓여있는 SQL 쿼리문들을 실제 데이터베이스에 날려 실행 시키는 작업

 

flush() 는 3가지 방법으로 호출될 수 있다.

  1. EntityManager 객체의 flush() 메소드를 직접 호출하거나, Spring Data Repository 객체의 saveAndFlush() 메소드를 통해 직접 호출할 수 있다. ⇒ 직접호출!
  2. Transaction 이 Commit 될 때 자동으로 호출된다. ⇒ 자동호출!
  3. JPQL 쿼리를 이용한 요청시 자동으로 호출된다. ⇒ 자동호출!

 

JPQL 쿼리는 영속성 컨텍스트의 1차 캐시를 우회하고 직접적으로 데이터베이스에 SQL 쿼리를 실행하기 때문에  JPQL 쿼리를 실행할 때는 영속성 컨텍스트에 있는 엔티티의 변경 사항이 자동으로 반영되지 않는다.  따라서 최신 데이터를 조회하기 위해 JPQL 쿼리를 실행하기 전에 flush() 메서드를 호출하여 영속성 컨텍스트에 쌓인 변경 사항을 데이터베이스에 즉시 반영해야 한다.

 

준영속 상태란?

말 그대로 영속적이지 않은 상태이기 때문에 영속성 컨텍스트의 관리를 받지 않음

 

준영속 상태를 영속 상태로 만들기 위해선?

merge 함수를 사용하면 된다

merge함수를 사용한다는것은 비영속 엔티티를 영속엔티티로 변환 시키는것이 아니고 비영속 엔티티를 복사해서 영속 엔티티로 새로 생성한다는 것이다

 

 

🤔 어떻게 활용할까?

평소에 사용하던 JPA Repository와 유사한 Spring Data Repository 객체의 save가 어떤식으로 동작하는지에 대해서 이해하게 되었다

📓 오늘의 한줄

"Words are, in my not-so-humble opinion, our most inexhaustible source of magic"

- J. K. Rowling(Harry Potter)-

'TIL' 카테고리의 다른 글

@DataJpaTest를 이용해서 단위 테스트 코드 작성하기  (0) 2024.06.21
Projection  (0) 2024.06.20
팀프로젝트 게임 채널 관리 앱 (회고)  (0) 2024.06.18
팀프로젝트 게임 채널 관리 앱 (5일차)  (0) 2024.06.17
Redis  (0) 2024.06.16