Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot construct instance of xxxx (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) 이슈 #150

Open
daadaadaah opened this issue Jul 17, 2023 · 0 comments

Comments

@daadaadaah
Copy link
Collaborator

daadaadaah commented Jul 17, 2023

What

  • com.fasterxml.jackson.databind.exc.InvalidDefinitionException는 Jackson 데이터 바인딩 라이브러리에서 발생하는 예외 중 하나로, 정의가 잘못되었거나 유효하지 않은 데이터를 역직렬화할 때 발생한다.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.hcommerce.heecommerce.order.dto.OrderForm` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
2023-07-18T02:38:50.124+09:00  WARN 53555 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.hcommerce.heecommerce.order.dto.OrderForm]]

Why

  • 스프링은 기본적으로 직렬화/역직렬화에 Jackson 라이브러리를 기본으로 사용하고 있는데, 그 Jackson 라이브러리는 직렬화/역직렬화 할 때, 기본생성자가 없으면 동작하지 않는다.
  • 그런데, 나는 다음과 같이 생성자가 있는데, 기본생성자가 없기 때문에 발생한 문제 였다.
@Getter
public class OrderForm {

    //.. 생략
    
    @Builder
    public OrderForm(
        UUID orderUuid,
        int userId,
        RecipientInfoForm recipientInfoForm,
        OutOfStockHandlingOption outOfStockHandlingOption,
        UUID dealProductUuid,
        int orderQuantity,
        PaymentMethod paymentMethod
    ) {
        this.userId = userId;
        this.orderUuid = orderUuid;
        this.recipientInfoForm = recipientInfoForm;
        this.outOfStockHandlingOption = outOfStockHandlingOption;
        this.dealProductUuid = dealProductUuid;
        this.orderQuantity = orderQuantity;
        this.paymentMethod = paymentMethod;
    }
}
  • 기본생성자가 없기 때문에 나타난 문제였다.
  • 왜 기본 생성자가 필요한 걸까?

How

  • JSON 데이터를 역직렬화하려면 매개변수가 없는 기본 생성자가 있거나,
  • Jackson 어노테이션을 사용하여 역직렬화할 생성자를 명시적으로 지정해야 합니다.
  • @ConstructorProperties 추가

@ConstructorProperties
생성자의 파라미터에 해당하는 getter 이름을 지정해주기 위한 자바 빈 애노테이션
Jackson이 JSON 형태의 데이터를 deserialize 할 때 기본 생성자를 사용해 인스턴스를 생성하고 setter로 필드 값을 셋팅한다.
그런데, immutable 객체의 경우 setter가 존재하지 않기 때문에 @ConstructorProperties로 호출할 생성자와 파라미터에 해당하는 getter 이름을 직접 지정

Before

@Getter
public class OrderForm {

    //.. 생략
    
    @Builder
    public OrderForm(
        UUID orderUuid,
        int userId,
        RecipientInfoForm recipientInfoForm,
        OutOfStockHandlingOption outOfStockHandlingOption,
        UUID dealProductUuid,
        int orderQuantity,
        PaymentMethod paymentMethod
    ) {
        this.userId = userId;
        this.orderUuid = orderUuid;
        this.recipientInfoForm = recipientInfoForm;
        this.outOfStockHandlingOption = outOfStockHandlingOption;
        this.dealProductUuid = dealProductUuid;
        this.orderQuantity = orderQuantity;
        this.paymentMethod = paymentMethod;
    }
}

After

@Getter
public class OrderForm {

     //.. 생략
    
    @Builder
    @ConstructorProperties({ // ✨ 추가
        "orderUuid",
        "userId",
        "recipientInfoForm",
        "outOfStockHandlingOption",
        "dealProductUuid",
        "orderQuantity",
        "paymentType"
    })
    public OrderForm(
       //.. 생략
    ) {
       //.. 생략
    }
}

Reference

@daadaadaah daadaadaah changed the title Cannot construct instance of 이슈 Cannot construct instance of 클래스명 (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) 이슈 Jul 17, 2023
@daadaadaah daadaadaah changed the title Cannot construct instance of 클래스명 (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) 이슈 Cannot construct instance of xxxx (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) 이슈 Jul 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant