Spring Boot 2.5.4 with Jackson 2.12.4
Given the following simplified enum...
@AllArgsConstructor
@Getter
public enum PaymentMethod {
CREDITCARD(1);
private long id;
}
... and a request object which shall be deserialized using Jackson:
@NoArgsConstructor
@Getter
@Setter
public class PaymentRequest {
@JsonProperty(value = "paymentMethod")
private PaymentMethod paymentMethod;
}
This works just fine. Now, I'd like to make the request object immutable, so I changed it to this:
@RequiredArgsConstructor
@Getter
public class PaymentRequest {
@JsonProperty(value = "paymentMethod")
private final PaymentMethod paymentMethod;
}
But this variant fails:
Cannot construct instance of 'PaymentRequest' (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
Is this some Jackson limitation when deserializing enums?
CodePudding user response:
This issue not because parameter is an Enum
, its because Lombok
and Jackson
doesn't work together in this scenario.
When deserializing to an immutable class, we need to explicitly mention that with Jackson
annotation. Usually we annotate the constructor. But in this case the constructor is created by Lombok
and Lombok
do not add those annotation.
The easy fix is, remove @RequiredArgsConstructor
annotation and create constructor yourself. Then annotate constructor as @JsonCreator
. Something like this,
@Getter
public class PaymentRequest {
@JsonProperty(value = "paymentMethod")
private final PaymentMethod paymentMethod;
@JsonCreator
public PaymentRequest(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}
}