56

I have inherited a certain bit code that has the @JsonProperty annotation on getter/setters. The purpose is so that when the object is serialized using the Jackson library, the fields have that specific name.

Current code:

private String fileName;

@JsonProperty("FILENAME")
public String getFileName()
{
    return fileName;
}

@JsonProperty("FILENAME")
public void setFileName(String fileName)
{
    this.fileName = fileName;
}

Now for another tool, I need to annotate the field with JsonProperty as well. So this will be my changed code:

@JsonProperty("FILENAME")
private String fileName;

@JsonProperty("FILENAME")
public String getFileName()
{
    return fileName;
}

@JsonProperty("FILENAME")
public void setFileName(String fileName)
{
    this.fileName = fileName;
}

Has anyone used this same annotation on both - the field as well as the getter/setters? I looked around on the net but didn't see anything.

I have compiled & run the code but I'm not sure if this would this cause any problems down the road. Any thoughts on this?

OceanBlue
  • 9,142
  • 21
  • 62
  • 84
  • 2
    As it is you wouldn't have a problem because you're not doing anything in the setter other than setting the value. However, if that were to change I'd worry about which one Jackson would use; if it picked the field, you might not get the behavior you're expecting. Unfortunately I can't find anything on the order of precedence for you. – Brian Roach Jul 17 '12 at 16:38
  • 1
    +1. Yes, an order of precedence would be useful, but of course they really should not *HAVE* different names. – OceanBlue Jul 18 '12 at 16:34

2 Answers2

55

My observations based on a few tests has been that whichever name differs from the property name is one which takes effect:

For eg. consider a slight modification of your case:

@JsonProperty("fileName")
private String fileName;

@JsonProperty("fileName")
public String getFileName()
{
    return fileName;
}

@JsonProperty("fileName1")
public void setFileName(String fileName)
{
    this.fileName = fileName;
}

Both fileName field, and method getFileName, have the correct property name of fileName and setFileName has a different one fileName1, in this case Jackson will look for a fileName1 attribute in json at the point of deserialization and will create a attribute called fileName1 at the point of serialization.

Now, coming to your case, where all the three @JsonProperty differ from the default propertyname of fileName, it would just pick one of them as the attribute(FILENAME), and had any on of the three differed, it would have thrown an exception:

java.lang.IllegalStateException: Conflicting property name definitions
Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • 4
    Nope, you are wrong. fileName will be used for deserialization and fileName1 for serialization (version 2.8.5) – user123454321 Jan 05 '17 at 19:48
  • 9
    actually the getter is annotated with fileName and will be used for serialization (from object instance to string), while the setter, annotated with fileName1, will be used deserialization (from string to object instance) – bardi Jan 19 '17 at 12:04
  • 1
    what is the reason here in using jsonproperty on both field and getter? if you have in on both getter and setter, why would you need it in field? – Konstantin Kulagin Oct 15 '18 at 14:05
12

In addition to existing good answers, note that Jackson 1.9 improved handling by adding "property unification", meaning that ALL annotations from difference parts of a logical property are combined, using (hopefully) intuitive precedence.

In Jackson 1.8 and prior, only field and getter annotations were used when determining what and how to serialize (writing JSON); and only and setter annotations for deserialization (reading JSON). This sometimes required addition of "extra" annotations, like annotating both getter and setter.

With Jackson 1.9 and above these extra annotations are NOT needed. It is still possible to add those; and if different names are used, one can create "split" properties (serializing using one name, deserializing using other): this is occasionally useful for sort of renaming.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • Intersting. So there wouldn't be a "conflicting name" error thrown in case of different names? – OceanBlue Jul 18 '12 at 19:49
  • No, since this is legal usage. There will be exceptions, however, if there are conflicts between multiple setter/getter methods, when it is not clear which one(s) to use. – StaxMan Jul 18 '12 at 21:22