26

Title says it all.

I would like to know what is the principial difference between putting JAXB annotation (like @XmlElement) on field / getter / setter. It seems to me that (in simple cases) it does not matter.

E.g. lets take this

class A  {
    private String a;

    public String getA() { return a; }

    public void setA(String a) { this.a = a; }
}

now it seems to me that it does not matter if I put @XmlElement on member field or on getter / setter. It just marshalls ok. Are there any usecases when I need to make difference and when it does matter?

When I go to unmarshall this (xml back to A) what JAXB does specifically?

I am using JAXB MOXy implementation

Thanks

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
stewenson
  • 1,282
  • 3
  • 15
  • 34

2 Answers2

20

By default JAXB impls will treat properties (get/set pairs), public fields (instance variables), and annotated non-public fields as mapped. If you just annotate a field you will get a duplicate mapped property exception.

If you want to annotate the field you should specify @XmlAccessorType(XmlAccessType.FIELD) on the class.

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • I am getting this exception that you mention despite using FIELD accessor : "Class has two properties of the same name "maxHttpConnectionsPerHost", this problem is related to the following location getMaxHttpConnectionsPerHost() and maxHttpConnectionsPerHost – shrewquest Aug 18 '16 at 13:04
  • I don't want to put your words in doubt, since I know you are the JAXB master. However, I think even with `@XmlAccessorType(XmlAccessType.NONE)` you can always put the annotations on field level. However, by contrast, if you use `@XmlAccessorType(XmlAccessType.FIELD)` it will assume that all public fields need to be exposed - even the public fields without annotations. So it would be more correct to state that: "If you don't want annotations on getters/setters then you should specify .... AccessType.FIELD ... on the class." – bvdb Apr 05 '18 at 16:00
  • 1
    What you say is correct and all alternatives work, but what is the difference of putting the annotation on the member versus the getters/setters? And what is the difference between putting it on the getter or the setter? What is the standard? Which should one choose and why? – mabi Sep 07 '21 at 20:22
2

I have found no differences in marking JAXB annotations on setter methods and getter methods. I tested both marshalling and unmarshalling, and they both worked fine. But you should only annotate one of them; either the getter method or the setter method; you cannot annotate both, else you will get a runtime exception like the following.

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
Rahul Khimasia
  • 473
  • 12
  • 24