JPA활용2_오류(No serializer found)

언젠간·2022년 9월 23일
1

에러 케이스

1. No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; 
nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested exception is 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]->jpabook.jpashop.domain.Order["member"]->jpabook.jpashop.domain.OrderItem["item"]->jpabook.jpashop.domain.Order["delivery"]->jpabook.jpashop.domain.Member$HibernateProxy$Xrie5JVt["hibernateLazyInitializer"])] with root cause

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]->jpabook.jpashop.domain.Order["member"]->jpabook.jpashop.domain.Member$HibernateProxy$Xrie5JVt["hibernateLazyInitializer"])
  • 원인
    • Lazy(지연로딩) 이기 때문에(DB에서 가져오는 것이 아니기 때문에) 값이 없음
  • 해결 방법
  1. application.yml 또는 application.properties에 추가
	spring:
      jackson:
        serialization:
          fail-on-empty-beans: false
  1. 에러 나는 엔티티 설정 Lazy - > EAGER로 변경, 좋은방법 아님

    jpabook.jpashop.domain.Order["member"] -> @ManyToOne(fetch = EAGER)
    jpabook.jpashop.domain.OrderItem["item"] -> @ManyToOne(fetch = EAGER)
    jpabook.jpashop.domain.Order["delivery"] -> @OneToOne(fetch = EAGER)

  2. 그래도 에러 발생 시, 해당 컬럼에 @JsonIgnore 추가

  3. 다 싫으면, Hibernate 5 Module 라이브러리 등록 / Bean 등록 하면 됨

    • ByteBuddyInterceptor(Hibernate)가 가짜 ProxyMember객체를 생성해서 만들어 둠
  4. 가장 좋은건, Lazy 강제 초기화 하면 됨

    • API 응답으로 Entity를 노출하면 안되기 때문
	@GetMapping("/api/v1/simple-orders")
    public List<Order> ordersV1() {
        List<Order> all = orderRepository.findAllByString(new OrderSearch());
        for (Order order : all) {
            order.getMember().getName(); //Lazy 강제 초기화
            order.getDelivery().getAddress(); //Lazy 강제 초기화
        }
        return all;
    }
profile
코딩왕이될사나이

0개의 댓글