본문 바로가기
JAVA/JPA

[JPA] 영속성 컨텍스트 개념 정리

by 개미가되고싶은사람 2024. 11. 1.

목차

     

    영속성 컨텍스트를 알아보기 전에, 엔티티 매니저 팩토리와 엔티티 매니저에 대해 간단히 설명하겠습니다.

     

     

    엔티티 매니저 팩토리

    엔티티 매니저 팩토리는 엔티티 매니저 인스턴스를 생성을 담당하는 객체입니다. 애플리케이션의 수명 동안 재사용되며, 애플리케이션이 시작될 때 한 번만 생성하는 것이 좋습니다. 기본적으로 요청마다 새로운 엔티티 매니저를 생성합니다.

     

     

    엔티티 매니저

    엔티티 매니저는 데이터베이스와 상호 작용하는 역할을 합니다. 요청이 있을 때마다 새로운 엔티티 매니저 인스턴스가 생성되어 데이터베이스와의 연결을 관리합니다. 이 엔티티 매니저는 내부적으로 데이터베이스 커넥션을 사용하여 다음과 같은 CRUD 작업을 수행합니다.

     

     

    영속성 컨텍스트(Persistence Context)

    애플리케이션과 DB 사이에서 객체(엔티티)를 영구적으로 저장하는 가상의 공간입니다. 엔티티 매니저(EntityManager)를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 저장하고 관리합니다.

     

     

     

    엔티티 생명주기 / 영속성 상태

    비영속 (new/transient)

    • 영속성 컨텍스트와 전혀 관계가 없는 상태

    영속 (managed)

    • 영속성 컨텍스트에 관리되는 상태

    준영속 (detached)

    • 영속성 컨텍스트에 저장되었다가 분리된 상태

    삭제 (removed)

    • 삭제된 상태
    //객체를 생성만 한 상태(비영속)
    Member member = new Member();
    member.setId("member1");
    member.setUsername(“회원1”);
    
    em.persist(member); // 영속 상태
    
    em.detach(member); //컨텍스트에서 분리, 준영속 상태
    em.clear(); // 영속성 컨텍스트의 모든 엔티티를 비우지만, 이미 관리되던 엔티티는 준영속 상태
    em.close(); // 영속성 컨텍스트를 종료, 관리되던 엔티티는 준영속 상태
    
    em.remove(member); // 영속석 컨텍스트에서 관리되던 엔티티 삭제, 삭제 상태
    
    em.flush(); // 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영, 영속성 컨텍스트 상태 변경X

     

     

     

    영속성 컨텍스트 장점

    1. 1차 캐시

    영속성 컨텍스트는 캐시와 유사한 개념으로, 1차 캐시 기능을 제공합니다. 영속성 컨텍스트는 데이터베이스에서 먼저 데이터를 찾는 것이 아니라 1차 캐시에서 데이터를 찾습니다. 그러나 트랜잭션이 끝나면 엔티티 매니저가 종료되어 영속성 컨텍스트와 1차 캐시도 사라지므로, 여러 요청에서 성능 향상을 기대하기 어렵습니다.

     

    2. 동일성 보장

    객체 인스턴스를 비교할 때는 각 인스턴스가 메모리에서 다른 메모리를 차지하므로 동일성이 보장되지 않습니다. 그러나 영속성 컨텍스트 내에서 동일한 엔티티를 컬렉션에 넣으면, 같은 식별자(PK)를 가진 엔티티는 동일한 객체 인스턴스를 참조하게 되어 동일성이 보장됩니다.

     

    3. 쓰기 지연

    JPA에서 em.persist() 메서드를 사용하여 객체를 영속성 컨텍스트에 저장하면 데이터베이스에 즉시 INSERT, UPDATE, DELETE  쿼리가 실행되지 않고, 영속성 컨텍스트는 객체의 상태를 관리하며 변경 사항을 추적합니다. 이때 변경된 내용은 모아두고, 실제 데이터베이스에 반영하는 과정인 flush가 호출될 때 모아둔 INSERT, UPDATE, DELETE 쿼리가 한 번에 실행됩니다.이러한 과정을 쓰기 지연라고 합니다. 생각해보면 트랜잭션 개념과 매우 유사합니다.

     

    4. 변경감지 (Dirty Checking)

    1차 캐시에 저장된 엔티티와 그 엔티티의 스냅샷을 비교하여 상태가 변경되었는지를 확인합니다. 엔티티의 상태가 변경되면 JPA는 현재 상태와 스냅샷을 비교하여 다르면 UPDATE 쿼리를 자동으로 생성하고 트랜잭션이 커밋될 때 데이터베이스에 반영합니다.

    더보기

    스냅샷이란?
    값을 가져올 때 최초의 값

    엔티티이란?
    데이터베이스의 데이터를 객체로 변환시킨 값

     

    5. 지연 로딩(Lazy Loading)

    지연 로딩은 연관 관계가 매핑된 엔티티를 조회할 때 먼저 프록시 객체를 반환하고, 실제 데이터가 필요할 때 쿼리를 실행하여 데이터를 가져오는 기능입니다.