'InvalidDefinitionException while using JsonCreator with JsonProperty.Access.READ_ONLY

I'm getting InvalidDefinitionException when trying to use @JsonCreator along with @JsonProperty(value = "version", access = JsonProperty.Access.READ_ONLY)

This is how my class look like:

@Entity
public class Example1 implements Serializable {

  private String field1;
  private int field2;
  private Example2 field3;

  public Example1(@JsonProperty(value = "field_1", access = JsonProperty.Access.READ_WRITE) String field1,
  @JsonProperty(value = "field_2", access = JsonProperty.Access.READ_ONLY) int field2,
  @JsonProperty(value = "field_3_1", access = JsonProperty.Access.READ_WRITE) String field31,
  @JsonProperty(value = "field_3_2", access = JsonProperty.Access.READ_WRITE) int field32
  ) {
    this.field1 = field1;
    this.field2 = field2;
    this.field3 = new Example2(field31, field32);
  }

  // getters and setters omitted
}

It's throwing the following exception :

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Argument #1 of constructor [constructor for com.test.example.model.Example1, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
 at [Source: (File); line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:249) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:165) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4145) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3995) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2878) ~[jackson-databind-2.9.0.pr3.jar:2.9.0.pr3]

My Environment details: I'm using Spring Boot 2.0.0.M2 version and Jackson 2.9.0.pr3.

My intention is to omit the field2 during deserialization.

I tried to use @JsonIgnore in the setter method of field2 as an alternative. Even, it didn't work with @JsonCreator.



Solution 1:[1]

You have two methods to ignore the property when deserialization

  1. use READ_ONLY

just add an annotation to the property you don't want deserialize

@JsonProperty(access = Access.READ_ONLY)
private String readOnly;
  1. use @JsonIgnore and @JsonProperty

this method should be careful, you should put the @JsonIgnore before the setter, and put the @JsonProperty before the getter. And for the property should clear without any annotation.

@JsonProperty
public String getJsonIgnoreSetter() {
    return jsonIgnoreSetter;
}

@JsonIgnore
public void setJsonIgnoreSetter(String jsonIgnoreSetter) {
    this.jsonIgnoreSetter = jsonIgnoreSetter;
}

At last, the full annotation example for @JsonIgnore, @JsonProperty, @JsonProperty(access = xxx).

The define of bean

public class MockBean{

    public MockBean() {
        super(MockBean.class);
    }

    public MockBean(String attr1, String ignore, String jsonIgnore, String jsonIgnoreGetter,
            String jsonIgnoreSetter, String jsonIgnoreProperties, String jsonIgnorePropertiesSetter,
            String jsonIgnorePropertiesGetter, String readOnly, String writeOnly) {
        super(MockBean.class);
        this.attr1 = attr1;
        this.ignore = ignore;
        this.jsonIgnore = jsonIgnore;
        this.jsonIgnoreGetter = jsonIgnoreGetter;
        this.jsonIgnoreSetter = jsonIgnoreSetter;
        this.jsonIgnoreProperties = jsonIgnoreProperties;
        this.jsonIgnorePropertiesSetter = jsonIgnorePropertiesSetter;
        this.jsonIgnorePropertiesGetter = jsonIgnorePropertiesGetter;
        this.readOnly = readOnly;
        this.writeOnly = writeOnly;
    }

    public String getAttr1() {
        return attr1;
    }

    public void setAttr1(String name) {
        this.attr1 = name;
    }

    public String getIgnore() {
        return ignore;
    }

    public void setIgnore(String ignore) {
        this.ignore = ignore;
    }

    public String getJsonIgnore() {
        return jsonIgnore;
    }

    public void setJsonIgnore(String jsonIgnore) {
        this.jsonIgnore = jsonIgnore;
    }

    @JsonIgnore
    public String getJsonIgnoreGetter() {
        return jsonIgnoreGetter;
    }

    @JsonProperty
    public void setJsonIgnoreGetter(String jsonIgnoreGetter) {
        this.jsonIgnoreGetter = jsonIgnoreGetter;
    }

    @JsonProperty
    public String getJsonIgnoreSetter() {
        return jsonIgnoreSetter;
    }

    @JsonIgnore
    public void setJsonIgnoreSetter(String jsonIgnoreSetter) {
        this.jsonIgnoreSetter = jsonIgnoreSetter;
    }

    public String getJsonIgnoreProperties() {
        return jsonIgnoreProperties;
    }

    public void setJsonIgnoreProperties(String jsonIgnoreProperties) {
        this.jsonIgnoreProperties = jsonIgnoreProperties;
    }

    public String getJsonIgnorePropertiesSetter() {
        return jsonIgnorePropertiesSetter;
    }

    @JsonIgnoreProperties
    public void setJsonIgnorePropertiesSetter(String jsonIgnorePropertiesSetter) {
        this.jsonIgnorePropertiesSetter = jsonIgnorePropertiesSetter;
    }

    @JsonIgnoreProperties
    public String getJsonIgnorePropertiesGetter() {
        return jsonIgnorePropertiesGetter;
    }

    public void setJsonIgnorePropertiesGetter(String jsonIgnorePropertiesGetter) {
        this.jsonIgnorePropertiesGetter = jsonIgnorePropertiesGetter;
    }

    public String getReadOnly() {
        return readOnly;
    }

    public void setReadOnly(String readOnly) {
        this.readOnly = readOnly;
    }

    public String getWriteOnly() {
        return writeOnly;
    }

    public void setWriteOnly(String writeOnly) {
        this.writeOnly = writeOnly;
    }

    private String attr1;
    @Ignore
    private String ignore;
    @JsonIgnore
    private String jsonIgnore;
    @JsonIgnore
    private String jsonIgnoreGetter;
    @JsonIgnore
    private String jsonIgnoreSetter;
    @JsonIgnoreProperties
    private String jsonIgnoreProperties;
    private String jsonIgnorePropertiesSetter;
    private String jsonIgnorePropertiesGetter;
    @JsonProperty(access = Access.READ_ONLY)
    private String readOnly;
    @JsonProperty(access = Access.WRITE_ONLY)
    private String writeOnly;
}

Test JSON

{
  "name": "name",
  "description": "description",
  "attr1":"attr1",
  "ignore": "ignore",
  "jsonIgnore": "jsonIgnore",
  "jsonIgnoreGetter": "jsonIgnoreGetter",
  "jsonIgnoreSetter": "jsonIgnoreSetter",
  "jsonIgnoreProperties": "jsonIgnoreProperties",
  "jsonIgnorePropertiesSetter": "jsonIgnorePropertiesSetter",
  "jsonIgnorePropertiesGetter": "jsonIgnorePropertiesGetter",
  "readOnly": "readOnly",
  "writeOnly": "writeOnly"
}

The result of deserialization: if the value is null, the value is not be deserialized.

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1