728x90
주문 + 배송정보 + 회원을 조회하는 API를 만들자
참고: 지금부터 설명하는 내용은 정말 중요합니다. 실무에서 JPA를 사용하려면 100% 이해해야 합니다. 안그러면 엄청난 시간을 날리고 강사를 원망하면서 인생을 허비하게 됩니다.
지연 로딩 때문에 발생하는 성능 문제를 단계적으로 해결해보자

- 무한루프 발생
- Why? -> order - Member를 순환참조한다.
- 해결하기 위해 양방향 연관관계가 있는 앤티티를 JsonIgnore 해준다.
Member,delivery,orderItem

- 에러 발생 500 ->org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor];
- Why? 지연로딩이기 때문에 실제 DB에서 데이터를 가지고 오는것이 아니라, 프록시객체를 생성해 넣어준다.(byteBudy가 프록시객체이다)
- Json Lib에서 해당객체를 어떻게 할수가 없기 때문에 에러를 발생시킨것이다.
- hibernate한테 해당지연로딩 객체를 뿌리지 말라고 해야된다.
해결
1. build.gradle에 추가

2. Bean 추가

- 에러가 해결되지만 성능상 좋지 않다.
- 엔티티를 그대로 노출하기 때문에 내가 필요하지 않는 필드를 조회해 오는 쿼리와, 앤티티를 변경하면 Api 스팩이 변경되는 문제가 발생한다.
프록시를 강제 초기화 하여 에러 해결 가능

- 주의: 엔티티를 직접 노출할 때는 양방향 연관관계가 걸린 곳은 꼭! 한곳을 @JsonIgnore 처리 해야 한다. 안그러면 양쪽을 서로 호출하면서 무한 루프가 걸린다.
- 참고: 앞에서 계속 강조했듯이 정말 간단한 애플리케이션이 아니면 엔티티를 API 응답으로 외부로 노출하는 것은 좋지 않다. 따라서 Hibernate5Module 를 사용하기 보다는 DTO로 변환해서 반환하는 것이 더 좋은 방법이다.
- 주의: 지연 로딩(LAZY)을 피하기 위해 즉시 로딩(EARGR)으로 설정하면 안된다! 즉시 로딩 때문에 연관관계가 필요 없는 경우에도 데이터를 항상 조회해서 성능 문제가 발생할 수 있다. 즉시 로딩으로 설정하면 성능 튜닝이 매우 어려워 진다.
- 항상 지연 로딩을 기본으로 하고, 성능 최적화가 필요한 경우에는 페치 조인(fetch join)을 사용해라!(V3 에서 설명)
728x90
'실전! 스프링 부트와 JPA 활용2(API 개발과 성능 최적화)' 카테고리의 다른 글
| Ch03. API 개발 고급(지연 로딩과 조회 성능 최적화) - 간단한 주문 조회 V3(Entity -> DTO로 변환(페치 조인 최적화)) (0) | 2021.12.20 |
|---|---|
| Ch03. API 개발 고급(지연 로딩과 조회 성능 최적화) - 간단한 주문 조회 V2(Entity -> DTO로 변환) (0) | 2021.12.20 |
| Ch02. API 개발 고급(준비) - API 개발 고급 소개, 조회용 샘플 데이터 입력 (0) | 2021.12.20 |
| Ch01. API 개발 기본 - 회원 조회 API (0) | 2021.12.19 |
| Ch01. API 개발 기본 - 회원 수정 API (0) | 2021.12.19 |