JPA/JPA Basic

[JPA] JPA 동작원리 ( 영속성 컨텍스트 )

IT록흐 2023. 5. 22. 17:59
반응형

 

 

[JPA] 패러다임의 불일치

어플리케이션 개발은 주로 객체지향언어로 이루어진다. 객체지향언어는 현실의 많은 문제를 코드로 구현하지만 문제가 있다. 데이터는 주로 관계형DB에 저장되는데 관계형DB와 어플리케이션은

lordofkangs.tistory.com

 

 

JPA는 객체지향 프로그래밍과 SQL 중심 프로그래밍 사이의 '패러다임 불일치' 문제를 해결하기 위해 등장했다.

 

 

 

 

 

이전에는 개발자가 SQL문을 직접 작성하여 테이블에 레코드를 추가해야 했다. 

 

JPA가 등장한 이후,

개발자는 JPA가 관리하는 인스턴스(엔티티)를 생성, 수정, 삭제만 하면 된다. ( 객체지향 관점 유지 가능 )

그러면 JPA가 자동으로 SQL문을 생성한다.

 

 

 

 

 

 

JPA는 DB 테이블의 레코드를 엔티티 인스턴스와 동기화하여 관리한다. 

 

1차 캐시 영역에 DB에서 데이터를 가져온 최초 상태를 '스냅샷'으로 관리한다. 만약 개발자가 영속화된 인스턴스, 즉 엔티티(Entity)의 필드데이터를 변경(setter)하면, 스냅샷과 비교하여 변경된 부분을 동기화 할 수 있는 UPDATE문을 자동생성하여 쓰기지연 SQL 저장소에 저장한다. 

 

만약 테이블에 레코드를 추가하고 싶은 거라면, 개발자는 엔티티 클래스의 인스턴스를 생성하여 persist 명령어로 영속화해야 한다. 영속화되어 JPA에 의해 상태가 추적되는 인스턴스를 두고 영속화 된 엔티티(Entity)라 부른다. 개발자가 엔티티를 영속화하면 1차캐시에 저장되고 자동으로 INSERT문이 생성되어 쓰기지연 SQL 저장소에 저장된다. 쓰기지연 SQL 저장소는 버퍼처럼 SQL문을 저장하므로, flush 명령이나 commit 명령을 받을 때, 여러 쿼리를 한번의 통신으로 DB에 실행할 수 있다. SQL문이 생성될 때마다 쿼리가 실행되지 않으므로 I/O 발생이 줄어들어 좋은 성능을 낼 수 있다.   

 

이로써 개발자는 엔티티를 영속화하고 변경하고 삭제하는 객체지향적 관점만 유지할 수 있게 된다. 테이블에 레코드를 조회하고 삽입하고 변경하고 삭제하는 SQL 작업은 JPA가 1차캐시와 SQL 쓰기지연저장소를 이용하여 자동으로 처리한다.  

 

영속성 관리

 

개발자는 엔티티를 영속화 하는 것이 가장 중요하다. JPA는 영속화 된 엔티티를 기준으로 SQL문을 생성하기 때문이다. 개발자가 영속화를 잘 제어할 수 있도록, JPA는 EntityManager를 제공한다. 

 

 

 

 

 

한 연예기획사가 있다. 연예기획사는 연예기획 부서와 매니지먼트 부서로 나뉜다. 매니지먼트 부서는 매니저를 파견하는데, 매니저는 아이돌 가능성이 있는 일반인을 캐스팅해서 연습생으로 만드는 역할을 한다. 연습생이 되면 연예기획의 관리를 받게 된다.

 

비유가 적절한지 모르겠지만 JPA가 동작하는 원리이다.

 

 

 

 

 

 

EntityManagerFactory에서 EntityMananger를 생성하고 EntityManger는 Entity클래스를 영속성컨텍스트에 등록한다. 영속성 컨텍스트에 등록된 엔티티는 생명주기가 생기고 관리된다.( Managed ) 영속성 컨텍스트 내부를 자세히 보자.

 

 

 

 

 

 

MemberA는 EntityManger 객체의 persist 메소드로 영속성 컨텍스트에 '등록'된다. 이를, '영속화'라고 부른다. 등록되면 엔티티 정보는 '1차 캐시'에 저장되고 엔티티 정보를 테이블로 삽입할 쿼리문은 '쓰기지연 SQL문 저장소'에 저장된다.

 

간단한 JPA 테스트 코드를 짜보았다.

@Slf4j
public class jpaTest {

    @Test
    void test(){
        
        //EntityManagerFactory 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("member");
        //EntityManager 생성
        EntityManager entityManager = emf.createEntityManager();
        //EntityTransaction 생성
        EntityTransaction tx = entityManager.getTransaction();
        
        //트랜잭션 시작
        tx.begin();

        try{
            Member member = new Member("사쿠라",26); // 엔티티생성 
            entityManager.persist(member); // 엔티티 영속화 
            tx.commit(); // 커밋 => Insert 쿼리문 전송
        }catch (Exception e){
            tx.rollback();
        }finally {
            entityManager.close();
        }
    }
}

 

자세한 내용은 다음 포스팅에서 다루어 보고 오늘은 결과만 보자.

 

Member 엔티티를 생성하고 persist로 영속화하면 1차캐시에 Member가 등록되고 쓰기지연 SQL 저장소에는 Insert문이 저장된다. 그리고 트랜잭션을 커밋하면 Insert문이 수행된다.

 

 

로그를 보면 INSERT문이 자동생성되어 수행되었음을 확인할 수 있다.

 

 

 

H2 DB에도 데이터가 삽입되어 있다. 

 

이처럼 JPA는 개발자가 직접 쿼리를 작성할 노고를 줄여준다. JPA는 1차캐시와 SQL쓰기지연 저장소를 유지하며 APP과 DB 사이에서 발생하는 패러다임 불일치 문제를 해결한다. 그리고 이는 EntityManager에 의해 관리된다. 

 

다음 포스팅에서는 구체적인 설정과정을 정리해보겠다.

 

 


 

 

참고자료

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

반응형