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)); }
Advertisement
Answer
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); }