Jaxb, Class has two properties of the same name
JavaXmlJaxbJava Problem Overview
with jaxb, i try to read an xml file only a few element in xml file are interesting, so i would like to skip many element
xml i try to read
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
<flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
<flx:Identification v="test1a"/>
<flx:BusinessType v="A01"/>
<flx:Product v="123a"/>
<flx:ResourceObject codingScheme="N" v="testa"/>
<flx:Period>
<flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
<flx:Resolution v="PT2H"/>
<flx:Pt>
<flx:P v="1"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
</flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
<flx:Identification v="test2a"/>
<flx:BusinessType v="A01"/>
<flx:Product v="a123b"/>
<flx:ResourceObject codingScheme="N" v="test2"/>
<flx:Period>
<flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
<flx:Resolution v="PT2H"/>
<flx:Pt>
<flx:P v="1"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
<flx:Pt>
<flx:P v="2"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
</flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>
my class
@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {
@XmlElement(name="TimeSeries")
protected List<TimeSeries> timeSeries;
public List<TimeSeries> getTimeSeries() {
if (this.timeSeries == null) {
this.timeSeries = new ArrayList<TimeSeries>();
}
return this.timeSeries;
}
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeSeries")
public class TimeSeries {
@XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;
@XmlElement(name = "Period")
protected Period period;
public RessourceObject getResourceObject() {
return this.resourceObject;
}
public void setResourceObject(RessourceObject resourceObject) {
this.resourceObject = resourceObject;
}
public Period getPeriod() {
return this.period;
}
public void setPeriod(Period period) {
this.period = period;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ResourceObject")
public class RessourceObject {
@XmlAttribute(name = "codingScheme")
protected String codingScheme;
@XmlAttribute(name = "v")
protected String v;
public String getCodingScheme() {
return this.codingScheme;
}
public void setCodingScheme(String codingScheme) {
this.codingScheme = codingScheme;
}
public String getV() {
return this.v;
}
public void setV(String v) {
this.v = v;
}
}
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Period")
public class Period {
@XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;
@XmlElement(name = "Pt")
protected List<Pt> pt;
public TimeInterval getTimeInterval() {
return this.timeInterval;
}
public void setTimeInterval(TimeInterval timeInterval) {
this.timeInterval = timeInterval;
}
public List<Pt> getPt() {
if (this.pt == null) {
this.pt = new ArrayList<Pt>();
}
return this.pt;
}
public void setPt(List<Pt> pt) {
this.pt=pt;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeInterval")
public class TimeInterval {
@XmlAttribute(name = "v")
private String timeIntervalPeriod;
public String getTimeIntervalPeriod() {
return this.timeIntervalPeriod;
}
public void setTimeIntervalPeriod(String timeIntervalPeriod) {
this.timeIntervalPeriod = timeIntervalPeriod;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Pt")
public class Pt {
@XmlElement(name = "P")
protected P p;
@XmlElement(name = "A")
protected A a;
public P getP() {
return this.p;
}
public void setP(P p) {
this.p = p;
}
public A getA() {
return this.a;
}
public void setA(A a) {
this.a = a;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "P")
public class P {
@XmlAttribute(name = "v")
protected String position;
public String getPosition(){
return this.position;
}
public void setPosition(String position){
this.position=position;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "A")
public class A {
@XmlAttribute(name = "v")
protected String calculatedAmount;
public String getCalculatedAmount() {
return this.calculatedAmount;
}
public void setCalculatedAmount(String calculatedAmount) {
this.calculatedAmount = calculatedAmount;
}
}
when i try to read the xlm file i get i get
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
this problem is related to the following location:
at public java.util.List testjaxp.ModeleREP.getTimeSeries()
at testjaxp.ModeleREP
this problem is related to the following location:
at protected java.util.List testjaxp.ModeleREP.timeSeries
at testjaxp.ModeleREP
i don't understand this error
edit: i use jaxb-impl-2.1.12
ok now i don't have any error, but when i check my object, timeSeries is null...
so maybe jaxb seem to have problem with flx?
Java Solutions
Solution 1 - Java
I also faced problem like this and i set this.
@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)
This will work 100%
Solution 2 - Java
You didn't specified what JAXB-IMPL version are you using, but once I had the same problem (with jaxb-impl 2.0.5) and solved it using the annotation at the getter level instead of using it at the member level.
Solution 3 - Java
There are multiple solutions but basicly if you annotate on variable declaration then you need @XmlAccessorType(XmlAccessType.FIELD)
, but if you prefer to annotate either a get- or set-method then you don't.
So you can do:
@XmlRootElement(name="MY_CLASS_A")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
@XmlElement(name = "STATUS")
private int status;
//.. and so on
}
Or:
@XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
private int status;
@XmlElement(name = "STATUS")
public int getStatus()
{
}
}
Solution 4 - Java
I've also seen some similiar issues like this.
I think, it's because of the place where we use the "@XMLElement" annotation in the (bean) class.
And I think, the JAXB (annotation processor) considers the member field & getter method of the same field element as different properties, when we use the @XMLElement annotation at the field level and throws the IllegalAnnotationExceptions exception.
Exception Message : > Class has two properties of the same name "timeSeries"
At Getter Method : > at public java.util.List testjaxp.ModeleREP.getTimeSeries()
At Member Field : > at protected java.util.List testjaxp.ModeleREP.timeSeries
Solution : Instead of using @XmlElement in the field, use it in the getter method.
Solution 5 - Java
just added this to my class
@XmlAccessorType(XmlAccessType.FIELD)
worked like a cham
Solution 6 - Java
Your JAXB is looking at both the getTimeSeries()
method and the member timeSeries
. You don't say which JAXB implementation you're using, or its configuration, but the exception is fairly clear.
> at public java.util.List testjaxp.ModeleREP.getTimeSeries()
and
> at protected java.util.List testjaxp.ModeleREP.timeSeries
You need to configure you JAXB stuff to use annotations (as per your @XmlElement(name="TimeSeries")
) and ignore public methods.
Solution 7 - Java
You need to configure class ModeleREP
as well with @XmlAccessorType(XmlAccessType.FIELD)
as you did with class TimeSeries
.
Have al look at OOXS
Solution 8 - Java
If we use the below annotations and remove the "@XmlElement" annotation, code should work properly and resultant XML would have the element names similar to the class member.
@XmlRootElement(name="<RootElementName>")
@XmlAccessorType(XmlAccessType.FIELD)
In case use of "@XmlElement" is really required, please define it as field level and code should work perfectly. Don't define the annotation on the top of getter method.
Had tried both the above approaches mentioned and got to fix the issue.
Solution 9 - Java
"Class has two properties of the same name exception" can happen when you have a class member x with a public access level and a getter/setter for the same member.
As a java rule of thumb, it is not recommended to use a public access level together with getters and setters.
Check this for more details: https://stackoverflow.com/questions/8002928/public-property-vs-private-property-with-getter
To fix that:
- Change your member's access level to private and keep your getter/setter
- Remove the member's getter and setter
Solution 10 - Java
These are the two properties JAXB is looking at.
public java.util.List testjaxp.ModeleREP.getTimeSeries()
and
protected java.util.List testjaxp.ModeleREP.timeSeries
This can be avoided by using JAXB annotation at get method just like mentioned below.
@XmlElement(name="TimeSeries"))
public java.util.List testjaxp.ModeleREP.getTimeSeries()
Solution 11 - Java
just declare the member variables to private in the class you want to convert to XML. Happy coding
Solution 12 - Java
Same problem I faced, I added
@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)
and now it is working.
Solution 13 - Java
I've just run into this problem and solved it.
The source of the problem is that you have both XmlAccessType.FIELD and pairs of getters and setters. The solution is to remove setters and add a default constructor and a constructor that takes all fields.
Solution 14 - Java
It will work when you put your annotation before the getters, and remove it from the protected attributes:
protected String codingScheme;
@XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
return this.codingScheme;
}
Solution 15 - Java
I had a service class with signature as below"
@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {
On run I got the same error for FetchIQAStatusResponseVO
fields. I just added a line on top of FetchIQAStatusResponseVO
:
@XmlAccessorType(XmlAccessType.FIELD) //This line added
public class FetchIQAStatusResponseVO {
and this resolved the issue.
Solution 16 - Java
ModeleREP#getTimeSeries()
have to be with @Transient
annotation. That would help.
Solution 17 - Java
Annotating with @XmlTransient
resolves that issue
@XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
Look at http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html for more details
Solution 18 - Java
A quick and simple way to fix this issue is to remove the @XmlElement(name="TimeSeries")
from the top of the variable declaration statement protected List<TimeSeries> timeSeries;
to the top of its getter, public List<TimeSeries> getTimeSeries()
.
Thus your ModeleREP
class will look like:
@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {
protected List<TimeSeries> timeSeries;
@XmlElement(name="TimeSeries")
public List<TimeSeries> getTimeSeries() {
if (this.timeSeries == null) {
this.timeSeries = new ArrayList<TimeSeries>();
}
return this.timeSeries;
}
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
}
Hope it helps!
Solution 19 - Java
I did trial and error and got the conclusion that, you only have to use either of both @XMLElement
or @XmlAccessorType(XmlAccessType.FIELD)
.
When to use which?
case 1 : If your field names and element name you want to use in xml file are different then you have to use @XMLElement(name="elementName")
. As this will bind fields with that element name and display in XML file.
case 2 : If fields names and respective element name in xml both are same then you can simply use @XmlAccessorType(XmlAccessType.FIELD)
Solution 20 - Java
Many solutions have been given, and the internals are briefly touched by @Sriram and @ptomli as well. I just want to add a few references to the source code to help understand what is happening under the hood.
By default (i.e. no extra annotations used at all except @XmlRootElement
on the root class), JABX tries to marshal things exposed via two ways:
- public fields
- getter methods that are named following the convention and have a corresponding setter method.
Notice that if a field is (or method returns) null
, it will not be written into the output.
Now if @XmlElement
is used, non-public things (could be fields or getter methods) can be marshalled as well.
But the two ways, i.e. fields and getter-methods, must not conflict with each other. Otherwise you get the exception.