Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 페치조인
- Spring
- DB
- 값타입
- DiscriminatorValue
- 고아객체
- Embeddable
- 영속성전이
- 관계형 데이터베이스
- 지연로딩
- 정렬
- fetch join
- Flush
- 분할상환분석
- commit
- 순수jpa
- 즉시로딩
- JPA
- n+1문제
- relational DB
- Amortized Analysis
- ROLLBACK
- 플러시
- DiscriminatorColumn
- 영속성 컨텍스트
- 엔티티 매핑
- relational database
- Spring Data JPA
- Algorithm
- MappedSuperclass
Archives
- Today
- Total
Jun's note
[JPA] 프록시(Proxy), 지연로딩(LAZY)와 즉시로딩(EAGER) 본문
728x90
프록시와 지연로딩이 서로 연관있기때문에 프록시, 지연로딩, 즉시로딩에 대해 정리해보겠다.
먼저 프록시가 나오게된 상황을 생각해보자.
(상황)
예를 들어, Member와 Team이 서로 연관되어있다. Member를 조회할때 Team을 항상 조회해야할까?
이 둘을 같이 조회해야되면 같이 조회하면되지만, 그렇지 않을때도 있다. 필요하지도 않는데 항상 같이 조회하면 성능이 저하될 수도 있다.
이럴땐 어떻게 해야하나?
(답은)
필요할때만 해당 엔티티를 조회하면 된다.(즉시로딩)
(이 상황에 대해 더 쉽게 생각해보면, 게시물을 조회할때 댓글창을 클릭하지도 않았는데 댓글도 같이 조회되어야하는가? 성능문제와 관련있기 때문에 이 문제에 있어 생각해봐야한다)
즉시로딩에서 실제 엔티티안에는 프록시라는 가짜 엔티티가 있다!
1. 프록시 (Proxy)
쉽게 말하면 가짜 엔티티이다.
엔티티를 실제 사용하는 시점까지 DB 조회를 미루고싶을때 사용한다.
- 사용 방법
- EntityManager.getReference() 메소드를 사용하면 프록시객체를 호출한다.
- 이 메소드를 호출하면, 실제 엔티티 객체를 만들지 않고 + DB에 조회하지 않는다.
- 특징
- 실제 엔티티 클래스를 상속받는다.
- 실제 클래스와 겉모양이 같다.
- 프록시 객체는 실제 객체의 참조(target)을 보관한다.
- 프록시 객체를 호출하면 실제 객체의 메소드를 호출한다.
- '프록시 객체의 초기화' 과정
- 프록시 객체 메소드를 호출했을때, 영속성 컨텍스트에 실제 엔티티가 없을 경우 DB에서 조회한다.
- 프록시 객체는 무조건 target을 통해 값을 얻는다. target에 값이 없으면 DB 조회를 하고, target에 값이 있으면 프록시 객체가 아닌 실제 객체를 반환한다.
- getId(식별자)를 구할때에는 프록시 객체로 구할 수 있다.
- 1. 프록시 객체 메소드가 호출되어, 프록시 객체가 가르키는 실제 객체(target)이 없을 경우(null) (실제객체는 영속성 컨텍스트안에 존재)
- 2. 초기화 요청 (target이 null이면 영속성 컨텍스트에도 존재하지 않음)
- 3. DB를 조회하여 영속성 컨텍스트에 저장
- 4. 영속성 컨텍스트에 있는 실제 엔티티를 가져온다. (프록시 객체 target에 실제 엔티티 매핑)
- 5. 프록시 객체의 target을 통해 원하는 값을 가져온다.
- 프록시 객체 사용시 주의사항 (예외)
- 프록시 객체를 초기화 할때 영속성 컨텍스트의 도움을 받아야 가능하다.
- 영속성 컨텍스트의 도움을 받을 수 없는 상황(준영속)에는 프록시를 초기화하면 문제 발생하다. (org.hibernate.LazyInitializationException 예외)
2. 지연로딩(LAZY)
- 필요한 엔티티만 조회한다. (DB에서)
- 실무에서는 지연로딩을 지향해야한다.
- @OneToMany, @ManyToMany 은 지연로딩을 기본 전략으로 사용한다.
3. 즉시로딩(EAGER)
- 어떤 한 엔티티를 조회할때, 그와 연관된 모든 엔티티를 다 조회한다.
- 단점: 필요이상으로 모든 엔티티를 조회하기 때문에 성능이 저하될 수도 있고, 어떻게 join되는지 자세히 알 수 없기때문에 즉시로딩을 사용하는 것은 매우 위험하다.
- @ManyToOne , @OneToOne 은 즉시로딩을 기본 전략으로 사용하고 있기 때문에 지연로딩을 명시해줘야한다.
- 사용 방법: @ManyToOne(fetch = FetchType.LAZY)
정리하면,
- 실무에서 지연로딩을 사용해야한다. 그런데 즉시로딩을 구해야하는 경우가 있으면 "지연로딩+join fetch"로 구현
- 지연로딩- 가끔 사용될때, 즉시로딩- 함께 자주 사용될때
참고
강의 : www.inflearn.com/course/ORM-JPA-Basic
서적 : <자바 ORM 표준 JPA프로그래밍> 김영한
'Programming > JPA' 카테고리의 다른 글
[JPA] 값 타입 (기본값 타입, 임베디드 타입, 컬렉션 값 타입) (0) | 2022.01.24 |
---|---|
[JPA] 영속성 전이(CASCADE)와 고아 객체 (0) | 2022.01.23 |
[JPA] 상속관계매핑, @MappedSuperclass (0) | 2022.01.14 |
[JPA] 다양한 연관관계 매핑 (다대일, 일대다, 일대일, 다대다) (0) | 2022.01.13 |
[JPA] 엔티티(Entity), 연관관계 매핑 (0) | 2022.01.13 |
Comments