I want to use @ConstructorProperties instead of @JsonCreator but it looks like it doesn't work in some scenarios.
@ConstructorProperties in jackson2 does not work when deserializing from array elements. Is there any way for both method1() and method2() to work with @ConstructorProperties?
I'm using jackson 2.13. Java 11.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.beans.ConstructorProperties;
import java.util.HashSet;
import java.util.Set;
class Scratch {
public static void main(String[] args) throws JsonProcessingException {
// THIS WORKS WHEN I USE @ConstructorProperties("value") ON CompId()
method1();
// THIS ONLY WORKS WHEN I USE @JsonCreator ON CompId()
method2();
}
private static void method2() throws JsonProcessingException {
Set<Long> compIds = new HashSet<>(1);
compIds.add(123L);
Dto1 dto1 = new Dto1(compIds);
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(dto1);
Dto2 dto = objectMapper.readValue(str, Dto2.class);
System.out.println(dto);
}
private static void method1() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
CompId compId1 = new CompId(123L);
String str = objectMapper.writeValueAsString(compId1);
CompId compId = objectMapper.readValue(str, CompId.class);
System.out.println(compId);
}
public static class Dto1 {
private final Set<Long> compIds;
@ConstructorProperties("compIds")
public Dto1(Set<Long> compIds) {
this.compIds = compIds;
}
public Set<Long> getCompIds() {
return compIds;
}
@Override
public String toString() {
return "Dto1{" +
"compIds=" + compIds +
'}';
}
}
public static class Dto2 {
private final Set<CompId> compIds;
@ConstructorProperties("compIds")
public Dto2(Set<CompId> compIds) {
this.compIds = compIds;
}
public Set<CompId> getCompIds() {
return compIds;
}
@Override
public String toString() {
return "Dto2{" +
"compIds=" + compIds +
'}';
}
}
static class CompId {
private long value;
//@JsonCreator
@ConstructorProperties("value")
public CompId(long value) {
this.value = value;
}
public long getValue() {
return value;
}
@Override
public String toString() {
return "CompId{" +
"value=" + value +
'}';
}
}
}
This is the stacktrace I get:
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `Scratch$CompId` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (123)
at [Source: (String)"{"compIds":[123]}"; line: 1, column: 13] (through reference chain: Scratch$Dto2["compIds"]->java.util.HashSet[0])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1728)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1353)