Skip to content

ValueInstantiationException when deserializing using a builder and UNWRAP_SINGLE_VALUE_ARRAYS #2608

@cadrake

Description

@cadrake

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>() {});
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    lombokIssue (likely) related to use of Lombok

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions