-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
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
Metadata
Metadata
Assignees
Labels
No labels