Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate properties with upper-case field name and JsonProperty annotation #1609

Closed
nbqyqx opened this issue Apr 19, 2017 · 6 comments
Closed

Comments

@nbqyqx
Copy link

nbqyqx commented Apr 19, 2017

Duplicate properties with upper-case field name and JsonProperty annotation

  • Jackson version: 2.8.8
  • TestCase
public class JacksonTest {
    public static void main(String[] args) {

        ObjectMapper  objectMapper = new ObjectMapper();
        Person person = new Person("neal", 30);

        try {
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(System.out, person);
            //new ByteArrayInputStream(objectMapper.writeValueAsBytes(person));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class Person {

        Person(String name, int age) {
            this.Name = name;
            this.Age = age;
        }

        public String getName() {
            return Name;
        }

        public void setName(String name) {
            Name = name;
        }

        public int getAge() {
            return Age;
        }

        public void setAge(int age) {
            Age = age;
        }

        @JsonProperty("Name")
        private String Name;

        @JsonProperty("Age")
        private int Age;

    }
}
  • Output:
{
  "name" : "neal",
  "age" : 30,
  "Name" : "neal",
  "Age" : 30
}

Expected:

{
  "Name" : "neal",
  "Age" : 30
}
  • Suspect cause:
    com.fasterxml.jackson.databind.ser.BeanSerializerFactory:138

Neal

@cowtowncoder
Copy link
Member

Not a bug but results from incompatible field/getter/setter naming -- fields would imply properties Name and Age (no annotation needed), but setters would imply properties name and age. Those will not automatically match (there is no assumption of case unification), so you end up with twice the properties you expect.

Fortunately there is a simple fix: just move annotations to either setters or getters (either one is fine): this will allow otherwise separate fields and getter/setter pairs to match

@nbqyqx
Copy link
Author

nbqyqx commented Apr 19, 2017

Why this works well? Fields introduce Name and Age, setters introduce name and age?

private static class Person {

        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

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

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @JsonProperty("Name")
        private String name;

        @JsonProperty("Age")
        private int age;

    }

@cowtowncoder
Copy link
Member

It works because all accessors initially match: "getAge()", "setAge()" and "age" infer age; and renaming of one renames them all as Age. Same for "name". Introspection always starts by checking inferred name: getters and setters use bean naming convention, field names used as is.
Accessors with same inferred name are grouped into one logical property candidate. After this, annotations are checked and apply to candidates, as a group.

@ronikrajan
Copy link

I have an instance where for below fields in my pojo:

private String oCurrNod;
public String getOCurrNod() {
    return this.oCurrNod;
}
public void setOCurrNod(String oCurrNod) {
    this.oCurrNod = oCurrNod;
}

During conversion from POJO to json it introduces new field: ocurrNod apart from the original field oCurrNod. Can you please comment on why would this be even though this naming convention seems to be right?

I also tried adding @JsonProperty annotation to getter to see if that fixes as suggested above in the comments. But this change doesn't fix the issue. I am using jackson 2.4.4

@cowtowncoder
Copy link
Member

@ronikraja Please use mailing list:

https://groups.google.com/forum/#!forum/jackson-user

for usage questions. Adding questions on closed issues is not a good medium for those.
If posting, include code to reproduce behavior (class definition is often not enough in itself).
It is also good to use a newer version of Jackson; 2.4.4 is rather old at this point.

But I can speculate on the problem: names are not compatible, due to inconsistent capitalization of the first 2 letters (field has 1; accessors 2).

@johnraychina
Copy link

mark

juherr added a commit to juherr/openapi-generator that referenced this issue Nov 18, 2022
In some case, Jackson will duplicate entries when the annotation is on field
See FasterXML/jackson-databind#1609
4brunu pushed a commit to OpenAPITools/openapi-generator that referenced this issue Jan 2, 2023
* Move Jackson annotation from field to getter

In some case, Jackson will duplicate entries when the annotation is on field
See FasterXML/jackson-databind#1609

* Update samples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants