JPA 동작 방식

개발자·2021년 11월 30일
0
post-thumbnail
post-custom-banner

엔티티(Entity)


엔티티란 데이터베이스의 테이블에 대응하는 클래스라고 생각하면 된다. @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 한다. 데이터베이스에 item 테이블을 만들고, 이에 대응되는 Item.java 클래스를 만들어 @Entity 어노테이션을 붙이면 이 클래스가 엔티티가 되는 것이다. 클래스 자체나 생성한 인스턴스도 엔티티라고 부른다.

엔티티 매니저 팩토리(Entity Manager Factory)


엔티티 매니저 팩토리는 엔티티 매니저 인스턴스를 관리하는 주체이다. 애플리케이션 실행 시 한 개만 만들어지며 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성한다.

엔티티 매니저(Entity Manager)


엔티티 매니저란 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공한다. 내부적으로 데이터베이스 커넥션을 사용해서 데이터베이스에 접근한다. 엔티티 매니저의 몇 가지 메소드를 살펴보자.

  • find() 메소드
    • 영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장한다.
  • persist() 메소드
    • 엔티티를 영속성 컨텍스트에 저장한다.
  • remove() 메소드
    • 엔티티 클래스를 영속성 컨텍스트에서 삭제한다.
  • flush() 메소드
    • 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영한다.

영속성 컨텍스트


JPA를 이해하기 위해서는 영속성 컨텍스트(Persistence Context)를 이해하는 것이 가장 중요하다. 엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

엔티티 생명주기

생명주기내용
비영속성(new)new 키워드를 통해 생성된 상태로 영속성 컨텍스트와 관련이 없는 상태
영속(managed)엔티티가 영속성 컨텍스트에 저장된 상태로 영속성 컨텍스트에 의해 관리되는 상태, 영속 상태에서 데이터베이스에 저장되지 않으며, 트랜잭션 커밋 시점에 데이터베이스에 반영
준영속 상태(detached)영속성 컨텍스트에 엔티티가 저장되었다가 분리된 상태
삭제 상태(removed)영속성 컨텍스트와 데이터베이스에서 삭제된 상태

영속성 컨텍스트 사용 시 이점

JPA는 왜 이렇게 영속성 컨텍스트를 사용하는 것일까? 바로 애플리케이션과 데이터베이스 사이에서 영속성 컨텍스트라는 중간 계층을 만들었기 때문이다. 이렇게 중간 계층을 만들면 버퍼링, 캐싱 등을 할 수 있다는 장점이 있다.

1차 캐시


영속성 컨텍스트에는 1차 캐시가 존재하며 Map<KEY, VALUE>로 저장된다. entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시를 조회한다. 엔티티가 존재할 경우 해당 엔티티를 반환하고, 엔티티가 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환한다.

동일성 보장


하나의 트랜젝션에서 같은 키값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장한다. 바로 1차 캐시에 저장된 엔티티를 조회하기 때문에 가능하다.

트랜잭션을 지원하는 쓰기 지연


영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재한다. entityManager.persist()를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소에 SQL문이 저장된다. 이렇게 SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL문들이 flush되면서 데이터베이스에 반영된다. 이렇게 모아서 보내기 때문에 성능에서 이점을 볼 수 있다.

변경 감지


JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷 값을 갖고 있다. 그리고 1차 캐시에 저장된 엔티티와 스냅샷을 비교 후 변경 내용이 있다면 UPDATE SQL문을 쓰기 지연 SQL 저장소에 담아둔다. 그리고 데이터베이스에 커밋 시점에 변경 내용을 자동으로 반영한다. 즉, 따로 update문을 호출할 필요가 없다.

JPA는 중간에 ORM을 두어 객체와 관계형 데이터베이스를 매핑시켜주는 역할을 하여 개발자는 SQL 작성으로 낭비하던 시간을 줄이고 비즈니스 로직에 집중하는 시간을 갖게 하며 객체지향적으로 프로그래밍을 할 수 있게 도와주는 큰 역할을 한다. Spring Data JPA는 구현체를 스프링에 맞춰 더욱 쉽게 사용할 수 있도록 도와주는 모듈이다.

해당 게시글은 변구훈, 『스프링 부트 쇼핑몰 프로젝트 with JPA』, 로드북, 2021를 참고하여 작성하였습니다.
profile
I DEVELOP THEREFORE, I AM 😄
post-custom-banner

0개의 댓글