Andreas Gelever
Andreas Gelever

Reputation: 2016

Jackson: deserialize with Builder along with standard setters/getters?

Is it possible with Jackson to deserialize json with Builder pattern as well as with default setter and getter approach?

My object is created with Builder that covers only required (final) fields, but I have non-final fields with some values as well that need to be deserialized with setters.

Here is the sample that throws an exception in an attempt to deserialize it with:

new ObjectMapper().readValue(json, Foo.class);

json - json representation serialized with default Jackson serializer, like:

objectMapper.writeValueAsString(foo);

class

@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonDeserialize(builder = Foo.Builder.class)
public class Foo {
    private final String key;
    private final Long user;
    private final String action;
    private final String material;
    private final String currency;

    private Foo(String key, Long user, String action, String material, String currency) {
        this.key = key;
        this.user = user;
        this.action = action;
        this.material = material;
        this.currency = currency;
    }

    public static class Builder {
        private  String key;
        private Long user;
        private String action;
        private String material;
        private String currency;

        @JsonProperty("key")
        public Foo.Builder withKey(String key) {
            this.key = key;
            return this;
        }

        @JsonProperty("user")
        public Foo.Builder withUser(Long user) {
            this.user = user;
            return this;
        }

        @JsonProperty("action")
        public Foo.Builder withAction(String action) {
            this.action = action;
            return this;
        }

        /// other 'with' setters....
    }

    @JsonProperty("state")
    private int state;

    @JsonProperty("stat")
    private String stat;

    @JsonProperty("step")
    private String step;
}

The exception it throws like :

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "state" (class com.Foo$Builder), not marked as ignorable (5 known properties: "key", "user", "action", "material", "currency",])

If not possible what workaround is the cheapest?

Upvotes: 1

Views: 1153

Answers (1)

NiVeR
NiVeR

Reputation: 9786

Two things that are suspicious:

  • You are willing to use the builder inside the Foo class. In that case you should correct the specification (SessionData.Builder.class is not correct in that case).
  • You are indeed trying to use an external builder. In this case you should remove or at least mark as ignorable the inner builder, this seems to be the reason of the excetpion you are getting.

In both cases you should make sure the final method to get the Foo instance is called build() otherwise you should annotate the builder with a @JsonPOJOBuilder(buildMethodName = "nameOfMethod", withPrefix = "set").

Upvotes: 2

Related Questions