-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
I am running into an issue with using @JsonDeserialize to deserialize via a builder when one field is really an array with a single value. I create a mapper and set DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS in order to unwrap the single object in the array but running my test gives Cannot construct instance of org.cadrake.POJOValue$POJOValueBuilder, problem: object is not an instance of declaring class. I Stepped through the jackson classes and it looks like when BuilderBasedDeserializer calls deserializeFromArray() and then passes the result to finishBuild(). The object has already been built by the super class and thus when finishBuild() uses reflection to call the build() method on the actual builder, it is failing because the object is of the target type not the builder type. I have included my example pojo's and test as well below, I generate the boiler plate getters/builder via lombok. I would like to help with a fix as well if this is more than a trivial change.
@Getter
@EqualsAndHashCode
@Builder
@JsonDeserialize(builder = ExamplePOJO.ExamplePOJOBuilder.class)
public class ExamplePOJO {
private final int id;
private final String name;
private final POJOValue value;
@JsonPOJOBuilder(withPrefix = "")
public static class ExamplePOJOBuilder {
}
}
@Getter
@EqualsAndHashCode
@Builder
@JsonDeserialize(builder = POJOValue.POJOValueBuilder.class)
public class POJOValue {
private final String subValue;
@JsonPOJOBuilder(withPrefix = "")
public static class POJOValueBuilder {
}
}
public class ExamplePOJOSerializationTest {
@Test
public void testDeserializationAndFail() throws IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
final String serialized = "{\"id\": 1, \"name\": \"test\", \"value\": [ {\"subValue\": \"123\"} ]}";
final ExamplePOJO pojoDeserialized = mapper.readValue(serialized, new TypeReference<ExamplePOJO>() {});
}
}