This is a simplified version of a problem I've been having. Given these classes:
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limits {
Limit minimum;
Limit maximum;
}
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limit {
@JsonValue
String value;
}
and this code:
Limits limits = Limits.builder()
.withMinimum(Limit.builder().withValue("One-Day").build())
.withMaximum(Limit.builder().withValue("One-Year").build())
.build();
System.out.println(objectMapper.writeValueAsString(limits));
it works as expected and gives me the following output:
{
"minimum": "One-Day",
"maximum": "One-Year"
}
However, when I try to deserialise the same JSON string, as follows:
String json = """
{"minimum":"One-Day","maximum":"One-Year"}
""";
objectMapper.readValue(json, Limits.class);
I get the following error:
Cannot construct instance of `Limit$Builder` (although at least one Creator exists):
no String-argument constructor/factory method to deserialize from String value ('One-Day')
at [Source: (String)"{"minimum":"One-Day","maximum":"One-Year"}"; line: 1, column: 12]
Is there a way to make it work without changing the data model or the JSON?
I tried adding @JsonCreator
to the Builder of Limit
as follows, but gives the same error
@Value
@Jacksonized
@Builder(builderClassName = "Builder", setterPrefix = "with")
public class Limit {
@JsonValue
String value;
public static final class Builder {
@JsonCreator
public Builder withValue(String value) {
this.value = value;
return this;
}
}
}
Appreciate any input on what I might be missing here.