JPA 면접

yshjft·2022년 9월 1일
0

Spring, JPA

목록 보기
1/16

JPA 사용 이유

JPA란 Java Persistence API로 Java 진영의 ORM(Object-Relational-Mapping) 기술에 대한 표준 명세

  • 생산성 증가
    • SQL을 작성하고 JDBC API를 사용하는 반복적인 일을 대신 처리해준다.
  • Object와 RDB 간의 패러다임 불일치 해결
    • 객체의 경우 상속, 객체 그래프 탐색 등이 가능

JPA 패러다임의 불일치 해결

객체지향 프로그래밍

  • 시스템의 복잡성을 제어할 수 있는 장치 제공 → 추상화, 상속, 캡슐화, 다형성
  • 참조를 이용하여 다른 객체와 연관관계를 가진다.
    • 참조에 접근해서 연관된 객체를 조회한다.
  • 동일성, 동등성을 이용하여 비교

관계형 데이터베이스

  • 데이터 중심
    • 추상화, 상속, 캡슐화, 다형성과 같은 개념은 없다
  • 외래 키를 사용해서 다른 테이블과 연관관계를 가진다.
    • 조인을 사용해서 연관된 테이블을 조회
  • PK 값으로 ROW를 구분

JPA의 상속 관계 해결

class Item { }

class Album extends Item { }

em.persist(Album);
em.find(Album.class, albumId);
  • JPA는 em.persist(Album)을 통해 INSERT INTO ITEMINSERT INTO ALBUM을 실행하게 된다.
  • JPA는 em.find(Album.class, albumId)을 하게되면 JOIN을 이용하여 필요한 데이터를 가져온다.
  • 상속관계 매핑을 이용
    • JOINED
    • SINGLE_TABLE
    • TABLE_PER_CLASS

JPA의 연관관계 해결

  • 만약 객체를 데이터베이스 방식에 맞추면 참조를 이용할 수 없다.
  • 객체지향 모델링을 적용(외래키가 아닌 참조를 이용하도록)하기 위해서는 인간 매퍼가 필요하다(노가다가 필요하다는 뜻).
    • 이러한 번거롭고 힘든일을 JPA가 해준다.
    • JPA는 연관관계에서 패러다임 불일치를 해결해준다.

JPA 객체 그래프 탐색 해결

  • 객체는 참조를 사용해서 연관된 객체를 찾을 수 있다.
  • SQL을 직접 다루게 되면 SQL에 의해 객체 그래프 탐색 범위가 제한된다.
  • JPA는 연관된 객체를 사용하는 시점에 적절한 query를 실행하여 객체 그래프 탐색의 범위에 제한이 없도록 한다.(Lazy Loading)

JPA 비교 해결

  • JPA는 동일한 트랜잭션에서 객체의 동일성을 보장한다.

패러다임 불일치 해결 관련

N+1 문제

  • 즉시 로딩
    • Spring Data JPA 메서드를 이용하여 조회하게 되는 경우 join을 이용해서 연관있는 객체까지 가져오게 된다
    • 하지만 JPQL을 이용하게되면 N+1 문제가 발생하게 된다.

      JPQL에선 입력 받은 query string이 그대로 SQL로 변환된다. "select m from Member m" 이 문장으로 당연히 Member만 SELECT 하게 된다. MEMBER를 쭉 다 가져와서 보니까 어 근데, Member 엔티티의 Team의 fetchType이 EAGER네? LAZY면 프록시를 넣으면 되겠지만, EAGER는 반환하는 시점에 다 조회가 되어 있어야 한다. 따라서, Member를 다 가져오고 나서, 그 Member와 연관된 Team을 다시 다 가져온다.

default_batch_fetch_size

  • 컬렉션 페치 조인 페이지 불가능 → 컬렉션 레이지 로딩 + 페이징 가능 + 최적화가 가능한 방법
  • 컬렉션이나 프록시 객체를 한꺼번에 정해놓은 개수 만큼 미리 당겨 놓는다.(in 쿼리에 정해 높은 개수 만큼 포함된다)
  • 1 + N → 1 + 1

JPA의 save와 saveAll의 성능 차이

save 는 1개 저장
saveAll은 안에 들어가 있는 N개의 데이터를 저장

N건의 데이터를 save와 saveAll을 사용해서 저장하게 된다면?
saveAll의 성능이 더 좋다.


save의 경우 n번의 proxy 과정(@Transactional, n번의 새로운 트랜잭션 생성)을 거치게 된다.

saveAll의 경우 1번의 proxy 과정(@Transactional, 1번의 트랙잭션을 지속해서 사용)을 거치게 된다.

JPA OSIV

OSIV(Open Session In View, Open EnitityManager In View)
데이터베이스 커낵션을 언제 반환할지 설정하는 옵션

(default) spring.jpa.open-in-view = true

  • 트랙잭션이 끝나도 반환을 하지 않는다.
  • 트랜잭션이 끝나도 api나 view 응답이 반환될 때까지 영속성 컨텍스트를 살려둔다.
  • ADMIN 에서 사용 권장

spring.jpa.open-in-view = false

  • 트랜잭션이 끝나면 반환
  • 트랜잭션이 끝나면 영속성 컨텍스트 정리
  • 서비스에서 사용 권장
profile
꾸준히 나아가자 🐢

0개의 댓글