[JPA] 지연로딩과 성능 최적화 - 1

2023. 4. 8. 23:35카테고리 없음

지연로딩과 성능 최적화 - 1

지연 로딩 때문에 발생하는 성능 이슈를 해결하기 위한 방법을 알아봅니다. 첫번째 강의는 지연 로딩과 엔티티로 데이터를 전달할 때 발생하는 오류에 대해 알아봤습니다.

지연 로딩

지연 로딩은 객체를 실제 사용하는 시점에 로딩하는 방식입니다. 지연 로딩을 사용하면 객체를 실제 사용하는 시점에 로딩하기 때문에 객체를 사용하지 않는 경우에는 로딩하지 않습니다.

지연 로딩은 처음 엔티티를 가져올 때 연관 객체까지 가져오지 않습니다. 이 때 Hibernate는 연관 객체를 상속한 프록시 객체를 생성해서 엔티티에 넣어둡니다.(보통 프록시를 초기화 한다고 얘기합니다.) 프록시 객체를 쓸 때 byteBuddy라는 라이브러리를 많이 쓰기 때문에 간혹 에러 로그에서 proxy, byteBuddyInterceptor라고 나오는 경우가 많습니다.

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
        No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) 
        (through reference chain: java.util.ArrayList[0]->com.jpabook.jpashop.domain.Order["member"]->com.jpabook.jpashop.domain.Member$HibernateProxy$dAvQ7Ilc["hibernateLazyInitializer"])

만약 이런 오류가 발생한다면 HibernateJakarta5Module(spring-boot 3.0이상, 그 이하 버전은 Hibernate5Module)을 추가해주면 됩니다. 그러면 JSON이 프록시 객체일 때 아무런 조치를 하지 않아 오류가 발생하지 않습니다.

    //SpringApplication.java
    @Bean
    Hibernate5JakartaModule hibernate5JakartaModule() {
        return new Hibernate5JakartaModule();
    }

    //build.gradle
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5-jakarta'

하지만 엔티티는 외부에 노출하면 안되기 때문에, 에러가 발생했을 때의 해결방법일 뿐 DTO를 사용해 데이터를 외부에 전달해야 합니다. 그럼 지금과 같은 오류를 맞닥뜨리지 않을 뿐더러 요청사항 변경으로 엔티티까지 변경되는 일이 없습니다. 따라서 DTO를 생성해 가급적 필요한 필드만 외부(클라이언트에)노출해야합니다.