[JPA] DTO 설계 이유

개발의 숩
|2023. 3. 18. 18:53
  • 엔티티를 직접 노출하는 것은 좋지 않다
  • 지연로딩으로 이루어진 것의 경우 실제 엔티티 대신에 프록시 존재
  • 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