138

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 content

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?

redfox26
  • 1,920
  • 3
  • 23
  • 32

20 Answers20

243

I also faced problem like this and i set this.

@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)

This will work 100%

CoolBeans
  • 20,350
  • 10
  • 83
  • 99
user2067376
  • 2,437
  • 1
  • 11
  • 4
26

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.

megathor
  • 479
  • 3
  • 7
  • That is correct I just removed the annotation from member and put it on setter level and it worked. – Varun Aug 03 '17 at 07:07
25

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()
    {
    }
}
Baked Inhalf
  • 2,894
  • 29
  • 42
24

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.

Sri
  • 4,227
  • 2
  • 34
  • 42
20

just added this to my class

@XmlAccessorType(XmlAccessType.FIELD)

worked like a cham

Ismael ozil
  • 565
  • 5
  • 6
11

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.

ptomli
  • 11,425
  • 4
  • 37
  • 61
8

You need to configure class ModeleREP as well with @XmlAccessorType(XmlAccessType.FIELD) as you did with class TimeSeries.

Have al look at OOXS

Nick
  • 2,809
  • 4
  • 27
  • 39
Mike
  • 121
  • 2
  • 8
8

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.

Tanorix
  • 230
  • 2
  • 16
8

"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: Public property VS Private property with getter?

To fix that:

  1. Change your member's access level to private and keep your getter/setter
  2. Remove the member's getter and setter
Community
  • 1
  • 1
Naor Bar
  • 1,715
  • 18
  • 15
6

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()
CoolBeans
  • 20,350
  • 10
  • 83
  • 99
Kondal Kolipaka
  • 3,281
  • 20
  • 26
6

just declare the member variables to private in the class you want to convert to XML. Happy coding

Tayab Hussain
  • 731
  • 8
  • 16
  • This should be the accepted solution. If you declare your member variable public, JABX will parse it in addition to getter/setter annotated methods and spit the exception. It's a great example where jabx library designer(s) went an extra mile on reflection trying to create flexibility and ended up facilitating invalid configurations. I fixed the problem on my own by changing one line of code at the time, tracing back to the member variable. – Vortex Oct 26 '16 at 04:36
5

Same problem I faced, I added

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

and now it is working.

Robert
  • 5,231
  • 43
  • 62
  • 114
Anil
  • 346
  • 3
  • 14
2

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.

Slava Imeshev
  • 1,322
  • 10
  • 14
2

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;
}
Lilia
  • 416
  • 6
  • 21
  • I too am running into the same problem. I too have observed that when the annotation is marked over the attributes I see this. Does this mean that always it should be placed before the getters?. – Pavan Dittakavi Apr 15 '18 at 16:35
  • @Pavan Yes I think so. Otherwise, it causes me the same problems than you – Lilia May 13 '18 at 11:52
1

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.

gvlasov
  • 16,604
  • 19
  • 65
  • 103
S Agrawal
  • 11
  • 2
1

ModeleREP#getTimeSeries() have to be with @Transient annotation. That would help.

Armer B.
  • 657
  • 2
  • 8
  • 20
0

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

kmaziarz
  • 154
  • 5
  • 1
    I think this is more a hack than a solution. This tells jaxb to ignore the method, instead of making it aware that it is the same thing. – Hans Wouters Aug 07 '15 at 14:20
  • Hack or not this IS the best solution to get around something that can't be described as anything short of a bug, I used @XmlAccessorType(XmlAccessType.FIELD) which was mostly ignored and adding @XmlTransient to each property was the only way to repair this problem. Thanks! – Ralph Ritoch Sep 02 '16 at 12:36
0

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!

0

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)

RamPrakash
  • 1,663
  • 3
  • 20
  • 25
0

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:

  1. public fields
  2. 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.

wlnirvana
  • 1,501
  • 15
  • 30