영속성 컨텍스트 - EntityManagerFactory와 EntityManage

wondi·2025년 1월 6일

영속성 컨텍스트란?

엔티티를 영구 저장하는 환경, 엔티티를 영구 저장하기 위해 보관하는 가상의 데이터베이스

  • 1차캐시 조회
    • 데이터를 조회할 때 먼저 1차캐시에서 찾고 없으면 DB에서 조회
  • 동일성보장
  • 변경감지
    • 엔티티를 수정하고 update가 필요 없음
  • 지연쓰기
    • commit하기 전까지는 데이터베이스에 쿼리문이 안날라감

등과 같이 엔티티 관리하며 성능 최적화를 함

EntityManagerFactory

EntityManagerFactory는 JPA에서 EntityManager을 생성하는 공장

특징

  1. 애플리케이션당 하나만 만듦
    • DB 연결 설정을 읽음
    • 커넥션 풀을 만듦
    • JPA가 사용할 때 매핑 정보를 검증하는 작업을 수행함
  2. 스레드가 안전함
    • 여러 스레드가 동시에 접근해도 EntityManager를 만들 수 있음
@Configuration
public class JpaConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        // EntityManagerFactory 설정
    }
}
  • 스프링부트에서 자동으로 EntityManagerFactory가 하나만 생성됨

EntityManager

JPA에서 실제로 데이터베이스 작업을 수행하는 핵심 객체

EntityManager em = emf.createEntityManager();

// 1. 엔티티 찾기
Member member = em.find(Member.class, "id1");

// 2. 엔티티 저장
em.persist(new Member("id2", "wondi2"));

// 3. 엔티티 수정 - 자동으로 변경 감지
member.setName("wondi");

// 4. 엔티티 삭제
em.remove(member);
  • EntityManager은 영속성 컨텍스트라는 데이터베이스를 관리함
  • EntityManager은 트랜잭션 단위로 동작함
    • 모든 데이터 작업이 성공적으로 완료되어야 최종 반영됨
EntityTransaction tx = em.getTransaction();
try {
    tx.begin(); // 트랜잭션 시작
    // 데이터베이스 작업 수행
    tx.commit(); // 모든 작업이 성공하면 커밋
} catch (Exception e) {
    tx.rollback(); // 문제가 생기면 모든 작업을 취소
}
  • EntityManager는 엔티티의 생명주기를 관리함

    • 비영속 : 영속성 컨텍스트와 관계 없는 새로운 상태
    • 영속 : 영속성 컨텍스트에 관리되는 상태
    • 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 삭제 : 삭제된 상태

비영속

  • 객체를 생성한 상태
  • 객체'만' 생성한 상태

영속

  • 객체를 생성한 상태(비영속)
  • 객체를 저장한 상태(영속)
    em.persist(member);

준영속, 삭제

em.detach(member);
  • 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.remove(member);
  • 객체를 삭제한 상태

1차캐시에서 조회

  • member1가 저장되어있다는 전제하에 조회가능
  • persist를 통해 1차캐시에 저장됨
Member member = new Member();
member.setID("member1")
member.setUsername("wondi");

//1차 캐시에 저장됨
em.persist(member);

//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");

  • 영속성 컨텍스트에 저장됨에 따라, 1차 캐시에 있는 member1을 바로 조회가능할 수 있음

데이터베이스 조회

Member findMember2 = em.find(Member.class, "member2");

member2를 했을 때,

  1. find("member2") : 1차 캐시에 없을 때!
  2. DB 조회
  3. 1차 캐시에 저장
  4. 반환
profile
Developer Wondi

0개의 댓글