Becker
Becker 의 TIL
Becker
  • 분류 전체보기 (30)
    • Computer Science (15)
      • Python (7)
      • Java (1)
      • Algorithm (0)
      • Database (3)
      • Network (1)
      • Openstack (2)
      • ETC (1)
    • 자동화 (3)
      • Github Action (1)
      • Airflow (0)
      • Docker (2)
    • 논문 리뷰 (1)
    • 서평 (3)
    • 끄적끄적 (8)
전체 방문자
오늘
어제

인기 글

티스토리

hELLO · Designed By 정상우.
Becker

Becker 의 TIL

[DB] JPA(Java Persistence API) 란 무엇인가?
Computer Science/Database

[DB] JPA(Java Persistence API) 란 무엇인가?

2022. 12. 21. 01:24

JPA, Hibernate, Spring Data JPA의 전반적인 흐름

JPA(Java Persistence API) 란 무엇인가?

JPA는 JAVA 진영에서 ORM(Object-Relational Mapping) 기술의 표준으로 사용되는 인터페이스의 모음이다. JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있다.

  • ORM 기술에 대한 자바 진영의 API 표준 명세
  • JPA의 구현체는 Hibernate, OpenJPA 와 같은 프레임워크가 존재함
  • ORM(Object-Relational Mapping)은 객체 관계 맵핑 기술

장점

  • SQL 이 아닌 Method로 DB를 조작할 수 있어, 개발자가 비지니스 로직을 구성하는데만 집중할 수 있다
  • 재사용 및 유지보수의 편리성이 증가한다
  • DBMS에 대한 종속성이 줄어든다

단점

  • JPA를 제대로 사용하기까지 걸리는 시간이 오래걸린다
  • 프로젝트 규모가 크고 복잡할 때 설계가 잘못된다면 속도저하 및 일관성(Consistency)이 무너진다
  • 온전한 ORM 만으로 프로젝트를 완성할 수 없다

영속성 컨텍스트

영속성 컨텍스트의 엔티티 관리 흐름

  • JPA 객체(Entity)의 생애주기를 관리하는 환경
  • 영속성 컨텍스트에 등록된 객체는 Database에 그 상태가 영속적으로 저장.
    • 영속성이란 영속성 컨텍스트에 Entity가 저장되고 있는 상태를 의미한다.
  • EntityManager를 통해 entity의 영속성이 관리된다

엔티티의 생명주기

엔티티 생명주기

  • 영속 : 영속성 컨텍스트에 의해 관리되는 상태
  • 비영속 : 영속성 컨텍스트에 의해 관리되지 않는 상태(한번도 관리된적 없는 상태)
  • 준영속 : 관리되었다 분리된 상태(Detached)
  • 삭제 : 영속성 컨텍스트에서 삭제되고 DB에서도 삭제된 상태

영속성 컨텍스트의 장점

영속성 컨텍스트

1. 1차 캐시

EntityManager에서 관리하는 cache table. 영속상태의 엔티티가 저장된다.

 

2. 동일성 보장

영속성 컨텍스트는 엔티티의 동일성을 보장한다.

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.print(a==b) // true

3. 변경 감지 (Dirty checking)

entity의 수정이 발생했을 때 따로 commit 하지 않아도, 영속성 컨택스트에서 변경 사항이 관리되고 DB에 반영된다.

 

※ 변경 감지의 흐름

  1. 트랙잭션을 커밋하면 entityManager의 내부에서 먼저 플러시가 호출된다.
  2. 엔티티와 스냅샷을 비교하여 변경된 엔티티를 찾는다.(checking)
  3. 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소에 저장한다.
  4. 쓰기 지연 저장소의 SQL을 플러시한다.
  5. 데이터베이스 트랜잭션을 커밋한다.

4. 쓰기 지연 SQL 저장소

SQL을 DB에 바로 반영하지 않고 메모리에 적재 한 뒤 나중에 flush() 호출 시 DB에 반영하기 위해 사용하는 저장소. DB에 트랜잭션을 한번씩 날리는것보다 한번에 모아서 날리는게 효율적이기 때문

 

5. 지연로딩(LAZY Loading)

두 엔티티가(A,B) 연관관계로 매핑이 되어있을 시 하나의 엔티티(A)를 조회하더라도 연관관계에 있는 엔티티(B)값에 접근하기 전까지 다른 엔티티를 위해 쿼리를 날리지 않는 기능

 

※ 플러시(flush)

영속성 컨텍스트의 쓰기 지연 SQL 저장소의 내용을 DB에 동기화하는 기능

호출 방법

1. em.flush() 직접 호출.

2. 트랜잭션 커밋시 플러시가 자동 호출.(commit : flush → commit!)

3. JPQL (Java Persistence Query Langauge) 쿼리 실행시 플러시가 자동 호출.

 


JPA N+1 문제

JPA를 사용할 경우 1개의 쿼리에 대해 설계 했으나 추가적으로 N 개의 쿼리가 더 발생해 총 N+1개의 쿼리를 날리게 되는 현상 의도치 않은 추가적인 쿼리에 의해 비지니스 로직이 긴 실행시간을 가지게됨

Why?

JPQL에서 메서드를 호출했을 때 연관관계를 무시하고 해당 테이블에 대한 조회를 하기 때문, 따라서 연관관계 엔티티를 조회하는 JPQL을 하나하나 생성해서 조회하기 때문이다.

 

- FetchType.LAZY : @OneToMany(fetch = FetchType.LAZY)

연관 관계로 지정된 엔티티를 프록시 객체 형태로 가져온 후 실제 사용할 때 해당 엔티티를 나중에 N 번 호출함

 

- FetchType.EAGER :@OneToMany(fetch = FetchType.EAGER)

연관 관계로 지정된 Entity를 조회할 경우 바로 추가적인 쿼리를 생성하여 조회(N번)

 

해결책

1. Fetch join 문을 사용해서 연관관계에 있는 Entity도 한번에 프록시 객체로 영속화하여 조회

@Query("SELECT p FROM Profile p join fetch p.user")
findAll()

public interface CommentRepository extends JpaRepository<Comment, Long> {

    @Query("select c from Comment c join fetch c.board")
    List<Comment> findAll();
}

2. @EntityGraph를 사용해서 연관관계에 있는 엔티티를 선언하여 한번에 조회

@Entity
@NamedEntityGraph(name = "graph.Department.employees",
                  attributeNodes = @NamedAttributeNode("employees"))
public class Department {
    // department fields and methods

    @OneToMany(fetch = FetchType.LAZY)
    private Set<Employee> employees;
}

@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long> {
    @EntityGraph(value = "graph.Department.employees")
    Department findById(Long id);
}

 

[참고]

https://dev-troh.tistory.com/150

https://junhyunny.github.io/spring-boot/jpa/java-persistence-api/

https://owin2828.github.io/devlog/2020/01/06/java-5.html

https://dbjh.tistory.com/77

https://ict-nroo.tistory.com/132

'Computer Science > Database' 카테고리의 다른 글

SQL syntax의 정리 - SELECT문  (2) 2022.12.27
[DB] 정규화(Normalization)에 대해서  (1) 2022.12.20
    'Computer Science/Database' 카테고리의 다른 글
    • SQL syntax의 정리 - SELECT문
    • [DB] 정규화(Normalization)에 대해서
    Becker
    Becker

    티스토리툴바