[23.09.28] 김영한님 JPA2 강의를 들으면서 해당 에러가 발생했다.

InvalidDefinitionException 을 구글링 검색해서 에러를 해결하는게 제일 빠른
방법이라는 것을 나도 알고있다. 다만, 에러가 생겼을 때 발생한 이유와 내가 생각했던 방식 , 실제 해결방법등을 기록하기 위해서 글을 작성했다.

1. 어떻게 발생했을까 ?

com.fasterxml.jackson.databind.exc.invalidDefinitionException
: No serializer found for class...

2. 이 에러를 보고 나는 무슨 생각을 했을까 ?

InvalidDefinitionException
에러 구문들에서 jackson.databind 라는 용어가 엄청 많이 나와서 구글링을 통해 먼저 용어들을 이해하려 했다.

2-1. Jackson

개념 : 데이터를 주고 받을 때 Json 형식으로 많이 사용한다.
데이터를 사용하는 대상이 편하게 사용하기위해 자주 사용.
그러면 jacksondms Json 데이터 구조를 처리해주는 라이브러리다.

알아야하는 점 : Jackson은 기본적으로 프로퍼티로 동작.
그럼 프로퍼티는 뭐지 ?
진짜 간략하게 생각하면 getter/settet를 묶어서 그냥 프로퍼티라고 부른다.

2-2. databind

바인딩이란 무엇일까 ?
자료형, 변수명, 변수값에 각각 int, num, 10 이라는 구체적인 값을 할당하는 각각의 과정을 바인딩이라고 한다. 값을 정하고 메모리에 또한 올려주는게 바인딩이라고 할 수 있다.

2-3. 그럼 뭘까 ?

  • Jackson 은 데이터를 일정한 형식에 바꿔주는 라이브러리 (여기선 Json)
  • Binding 은 타입, 값을 설정해주는 것이라고 이해를 하면..

아 ! 데이터를 바꿔주는 과정에서 타입 / 값 설정이 안됐을 수 있겠구나 라는 생각이 들었다.(맞았다)

3. 내가 했던 해결 방법


OrderApI

@RestController
@RequiredArgsConstructor
public class OrderApi {
    private final OrderRepository orderRepository;
    private final OrderQueryService orderQueryService;

    @GetMapping("/orders/api/v2")
    public List<OrderDtoV2> ordersV2(){
        List<OrderDtoV2> result = orderQueryService.ordersV2();
        return result;
    }
}

OrderDtoV2

@Data
public class OrderDtoV2 {

    private Long orderId;
    private String name;
    private LocalDateTime orderDate;
    private OrderStatus orderStatus;
    private Address address;
    private List<OrderItemDto> orderItems;

    public OrderDtoV2(Order order){
            orderId = order.getId();
            name = order.getMember().getName();
            orderDate = order.getOrderDate();
            orderStatus = order.getStatus();
            address = order.getDelivery().getAddress();
            orderItems = order.getOrderItems().stream().map(o-> new OrderItemDto(o)).collect(Collectors.toList());
    }

    @Data
    static class OrderItemDto{
        private String itemName;
        private int orderPrice;
        private int count;

        public OrderItemDto(OrderItem orderItem){
            itemName = orderItem.getItem().getName();
            orderPrice = orderItem.getOrderPrice();
            count = orderItem.getCount();
        }
    }
}

여기부터는 제 생각입니다. 틀릴 수 있어요.

  1. @RestController 는 응답 데이터를 보낼 때 Json 형식으로 보낸다.
  2. 그러면 지금 OrderDtoV2 를 반환하고 있는데 객체 -> Json 변경이 필요하다.
  3. Jackson 라이브러리를 통해 Json 으로 변경시도
  4. 프로퍼티 형식으로 데이터를 가져옴.

어 근데 @Getter Setter 가 없네 .. ? (나는 @Data가 누락 됐었다)
결국 데이터를 읽을 수 없어서 에러가 뜬 것이었다. (Getter 또는 Public)

4. 근데 serializer 는 뭐지 ?

직렬화는 객체의 상태를 바이트 스트림으로 변환하는 것이고 역직렬화는 그 반대의 작업입니다

profile
한전 퇴사 후 독일가기 위한 기록

0개의 댓글