- 엔티티를 직접 노출하는 것은 좋지 않다
- 지연로딩으로 이루어진 것의 경우 실제 엔티티 대신에 프록시 존재
- jackson 라이브러리는 기본적으로 이 프록시 객체를 json으로 어떻게 생성해야 하는지 모름 → 예외 발생
- Hibernate5Module을 스프링 빈으로 등록하면 해결 (Spring boot 사용중)
- 이 옵션을 사용할 경우 양방향 연관관계는 계속 로딩하게 된다. 따라서 @JsonIgnore 옵션을 한곳에 주어야 한다.
Hibernate5Module 등록
build.gradle에 라이브러리 추가
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
JpashopApplication에 코드 추가
@Bean
Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
- 기본적으로 초기화된 프록시 객체만 노출, 초기화 되지 않은 프록시 객체는 노출 안함
다음과 같이 설정하면, 강제로 지연 로딩 가능
Bean
Hibernate5Module hibernate5Module() {
Hibernate5Module hibernate5Module = new Hibernate5Module();
//강제 지연 로딩 설정
hibernate5Module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING,
true);
return hibernate5Module;
}
주의 : 엔티티를 직접 노출할 때는 양방향 연관관계가 걸린 곳은 꼭! 한곳을 @JsonIgnore 처리 해야 한다
안그러면 양쪽을 서로 호출하면서 무한 루프가 걸린다
참고 : 정말 간단한 애플리케이션이 아니면 엔티티를 API 응답으로 외부로 노출하는 것은 좋지 않다. 따라서 Hibernate5Module를 사용하기보다는 DTO로 변환해서 반환하는 것이 더 좋은 방법이다
주의 : 지연 로딩(LAZY)을 피하기 위해 즉시 로딩(EARGR)으로 설정하면 안된다
즉시 로딩때문에 연관관계가 필요 없는 경우에도 데이터를 항상 조회해서 성능 문제가 발생할 수 있다. 즉시 로딩으로 설정하면 성능 튜닝이 매우 어려워 진다
💡 항상 지연 로딩을 기본으로 하고, 성능 최적화가 필요한 경우에는 fetch join을 사용해라
'TIL' 카테고리의 다른 글
[JPA] API 개발 고급 정리 (1) | 2023.03.21 |
---|---|
[JPA] 페이징과 한계돌파 (0) | 2023.03.20 |
[JPA] N+1 문제 (0) | 2023.03.19 |
[JPA] respository에 DTO 사용 ? (0) | 2023.03.18 |
[JPA] Entitiy 대신 ResponseDto,RequestDto 사용, 그 이유 (0) | 2023.03.17 |