I am attempting to deserialize a JSON object stored in CouchDb using Jackson. This object needs to deserialize into a pojo that contains overloaded methods. When I attempt to retrieve the object from couch and do the deserialization I get the following exception:
org.ektorp.DbAccessException: org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property "multiplier": com.db.commodities.framework.sdos.model.security.EqOpt#setMultiplier(1 params) vs com.db.commodities.framework.sdos.model.security.EqOpt#setMultiplier(1 params)
I tried to annotate the setter I would like Jackson to use, but that appears to not have worked.
@JsonProperty("multiplier") public void setMultiplier(SDOSAttribute multiplier) { this.multiplier = multiplier; } public void setMultiplier(double multiplier) { this.multiplier.setValue(String.valueOf(multiplier)); }
How do I configure Jackson to properly deserialize using a specific method? Or am I approaching this problem the wrong way?
EDIT:
I have made the following changes. This seems to work, but is a little uglier. If anyone has a better way to do this please feel free to share and I will gladly accept.
@JsonProperty("multiplier") protected void setMultiplierAttribute(SDOSAttribute multiplier) { this.multiplier = multiplier; } @JsonIgnore public void setMultiplier(double multiplier) { this.multiplier.setValue(String.valueOf(multiplier)); }
The readValue() method is used to parse (deserialize) JSON from a String, Stream, or File into POJOs. On the other hand, the writeValue() method is used to turn POJOs into JSON (serialize).
The @JsonProperty annotation is used to map property names with JSON keys during serialization and deserialization. By default, if you try to serialize a POJO, the generated JSON will have keys mapped to the fields of the POJO.
The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON. The Jackson ObjectMapper can also create JSON from Java objects.
Deserialization annotations are used when we deserialize JSON string into an Object. Jackson library provides several deserialization annotations such as @JsonCreator, @JacksonInject, @JsonAnySetter, etc. These annotations are mostly used in setter.
It's not necessary to change the name of the setter method to avoid ambiguity. You're otherwise on the right track with @JsonIgnore
. With @JsonIgnore
on all of the same-named methods to be ignored, the one to use does not need the @JsonProperty
annotation.
Here's a simple example to demonstrate this point.
input.json: {"value":"forty-two"}
Foo.java:
import java.io.File; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.ObjectMapper; public class Foo { String value; public String getValue() {return value;} public void setValue(String value) {this.value = value;} @JsonIgnore public void setValue(int value) {this.value = String.valueOf(value);} public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); Foo foo = mapper.readValue(new File("input.json"), Foo.class); System.out.println(mapper.writeValueAsString(foo)); } }
If you don't want to alter the pristine POJO defs with a Jackson annotation, then you can use a MixIn
.
import java.io.File; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.ObjectMapper; public class Foo { String value; public String getValue() {return value;} public void setValue(String value) {this.value = value;} public void setValue(int value) {this.value = String.valueOf(value);} public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.getDeserializationConfig().addMixInAnnotations(Foo.class, IgnoreFooSetValueIntMixIn.class); Foo foo = mapper.readValue(new File("input.json"), Foo.class); System.out.println(mapper.writeValueAsString(foo)); } } abstract class IgnoreFooSetValueIntMixIn { @JsonIgnore public abstract void setValue(int value); }
In Jackson > 2.4 use directly :
mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With