Jaxb、Classには同じ名前の2つのプロパティがあります


120

jaxbを使用して、xmlファイルを読み込もうとすると、xmlファイル内のいくつかの要素のみが興味深いので、多くの要素をスキップしたいと思います

XMLコンテンツ

読んでみたxml

<?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>

私のクラス

@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;
}
}

XLMファイルを読み込もうとすると、

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

私はこのエラーを理解していません

編集:私はjaxb-impl-2.1.12を使用します

さて、エラーはありませんが、オブジェクトをチェックすると、timeSeriesはnullです...

おそらくjaxbはflxに問題があるように見えるのでしょうか?

回答:


204

私もこのような問題に直面し、これを設定しました。

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

これは100%機能します


8
同じ問題がありました。@XmlAccessorType(XmlAccessType.FIELD)だけを追加しても機能します
Ram Dutt Shukla

2
私がして、問題を解決削除@XmlAccessorType(XmlAccessType.FIELD)注釈を
ハンスWOUTERS

奇妙に聞こえるかもしれませんが、注釈のペア\ @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD)を\ @XmlRootElementだけに減らすことで、この例外を取り除きました
Alex InTechno

3
JAXBアノテーションの内部クラスで同じ問題が発生しました。@XmlAccessorType(XmlAccessType.FIELD)を内部クラスに配置することができました!
Shoaib Khan 2016

素晴らしい、ありがとうございました。ロンボクとの組み合わせで非常に役立つ
マイケルヘグナー1913

25

使用しているJAXB-IMPLバージョンを指定していませんが、同じ問題(jaxb-impl 2.0.5を使用)が発生し、メンバーレベルではなくゲッターレベルでアノテーションを使用して解決しました。


正解です。メンバーからアノテーションを削除し、セッターレベルに配置するだけで機能しました。
Varun 2017

22

このような同様の問題もいくつか見ました。

私はそれが理由のだ、と思うところ私たちは、「使用@XmlElement注釈を(豆)クラスで。

また、フィールドレベルで@XMLElementアノテーションを使用してIllegalAnnotationExceptions例外をスローすると、JAXB(アノテーションプロセッサ)は同じフィールドエレメントのメンバーフィールドとゲッターメソッドを異なるプロパティと 見なします。

例外メッセージ:

クラスには、「timeSeries」という同じ名前の2つのプロパティがあります

ゲッターメソッドで:

    at public java.util.List testjaxp.ModeleREP.getTimeSeries()

メンバーフィールド:

    at protected java.util.List testjaxp.ModeleREP.timeSeries

解決策: 代わりに使用しての@XmlElementをして、フィールドでそれを使用するゲッターメソッド。


16

これを私のクラスに追加しました

@XmlAccessorType(XmlAccessType.FIELD)

チャムのように働いた


ロンボクの@Dataアノテーションと連動します。
digz6666

16

複数の解決策がありますが、基本的に、変数宣言に注釈を付ける場合はが必要ですが@XmlAccessorType(XmlAccessType.FIELD)、getメソッドまたはsetメソッドのいずれかに注釈を付ける場合は、そうしません。

だからあなたはできる:

@XmlRootElement(name="MY_CLASS_A")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
    @XmlElement(name = "STATUS")   
    private int status;
   //.. and so on
}

または:

@XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
    private int status;

    @XmlElement(name = "STATUS")         
    public int getStatus()
    {
    }
}

素晴らしい。ありがとう:) +1
アニッシュB.

11

あなたのJAXBはgetTimeSeries()メソッドとメンバーの両方を調べていtimeSeriesます。使用しているJAXB実装やその構成は明らかにしていませんが、例外はかなり明確です。

public java.util.List testjaxp.ModeleREP.getTimeSeries()で

そして

保護されているjava.util.Listでtestjaxp.ModeleREP.timeSeries

アノテーションを使用するようにJAXBを構成し(のとおり@XmlElement(name="TimeSeries"))、パブリックメソッドを無視する必要があります。


私はすでにしています:@XmlElement(name = "TimeSeries")protected List <TimeSeries> timeSeries;
redfox26

4
また、(XmlAccessType.FIELD)を(XmlAccessType.NONE)に変更します
。XmlElementを

私はまた、変数に@XmlTransientを追加するために必要な
HomeIsWhereThePcIs

8

あなたは、configureクラスに必要なModeleREPだけでなくて@XmlAccessorType(XmlAccessType.FIELD)、あなたがクラスで行ったようにTimeSeries

でアル見てOOXS


8

以下のアノテーションを使用して「@XmlElement」アノテーションを削除すると、コードは適切に機能し、結果のXMLにはクラスメンバーに類似した要素名が含まれます。

@XmlRootElement(name="<RootElementName>")
@XmlAccessorType(XmlAccessType.FIELD)

「@XmlElement」の使用が本当に必要な場合は、フィールドレベルとして定義してください。コードは完全に機能します。getterメソッドの上部にアノテーションを定義しないでください。

上記の両方のアプローチを試し、問題を修正しました。


7

「クラスには同じ名前の例外の2つのプロパティがあります」は、パブリックアクセスレベルを持つクラスメンバーxと、同じメンバーのゲッター/セッターがある場合に発生する可能性があります。

Javaの経験則として、パブリックを使用することは推奨されませんゲッターおよびセッターと一緒にアクセスレベル。

詳細については、これを確認してください: パブリックプロパティVSゲッター付きプライベートプロパティ?

それを修正するには:

  1. メンバーのアクセスレベルをプライベートに変更し、ゲッター/セッターを維持する
  2. メンバーのゲッターとセッターを削除する

6

これらは、JAXBが調べている2つのプロパティです。

public java.util.List testjaxp.ModeleREP.getTimeSeries()  

そして

protected java.util.List testjaxp.ModeleREP.timeSeries

これは、後述のようにgetメソッドでJAXBアノテーションを使用することで回避できます。

@XmlElement(name="TimeSeries"))  
public java.util.List testjaxp.ModeleREP.getTimeSeries()

5

XMLに変換するクラスで、メンバー変数をプライベートに宣言するだけです。ハッピーコーディング


これは受け入れられる解決策です。メンバー変数をpublicと宣言すると、JABXはgetter / setterアノテーション付きメソッドに加えてそれを解析し、例外を吐き出します。これは、jabxライブラリデザイナーが柔軟性を生み出すためにリフレクションをさらに強化し、最終的に無効な構成を容易にした優れた例です。一度に1行のコードを変更し、メンバー変数までさかのぼって自分で問題を修正しました。
Vortex

4

私が直面した同じ問題、私は追加しました

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

そして今それは働いています。


3

アノテーションをゲッターの前に置き、保護された属性から削除すると機能します。

protected String codingScheme;

@XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
    return this.codingScheme;
}

私も同じ問題に直面しています。私も、注釈が属性の上にマークされているときに、これが表示されることを確認しました。これは、常にゲッターの前に配置する必要があるということですか?
Pavan Dittakavi

@Pavanはい、そう思います。それ以外の場合は、あなたと同じ問題が発生します
リリア

2

私はこの問題に遭遇し、それを解決しました。

問題の原因は、XmlAccessType.FIELDとゲッターとセッターのペアの両方があることです。解決策は、セッターを削除し、デフォルトのコンストラクターとすべてのフィールドを受け取るコンストラクターを追加することです。


私は同じエラーがあり、あなたが言及した注釈はそれを解決しました、ありがとう!
gyorgyabraham 2013

1

以下のような署名のサービスクラスがありました。」

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

実行時に、FetchIQAStatusResponseVOフィールドに対して同じエラーが発生しました。上に行を追加しましたFetchIQAStatusResponseVO

@XmlAccessorType(XmlAccessType.FIELD) //This line added
public class FetchIQAStatusResponseVO {

これで問題が解決しました。


1

ModeleREP#getTimeSeries()する必要が@Transient注釈。それは役に立ちます。


0

注釈を@XmlTransient付けることで問題が解決します

@XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
   this.timeSeries = timeSeries;
}

詳細については、http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.htmlを参照してください


1
これは解決策というよりはハックだと思います。これは、同じであることを認識させる代わりに、jaxbにメソッドを無視するように指示します。
Hans Wouters、2015

ハックであるかどうかは、バグではないものとして説明できないものを回避するための最善の解決策です。ほとんど無視されていた@XmlAccessorType(XmlAccessType.FIELD)を使用し、@ XmlTransientを各プロパティに追加することが唯一の方法でしたこの問題を修復します。ありがとう!
Ralph Ritoch 16

0

この問題をすばやく簡単に修正するに@XmlElement(name="TimeSeries")は、変数宣言ステートメントprotected List<TimeSeries> timeSeries;の先頭からゲッターの先頭までを削除しpublic List<TimeSeries> getTimeSeries()ます。

したがって、ModeleREPクラスは次のようになります。

@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;
  }
}

それが役に立てば幸い!


あなたは「簡単な方法」に言及します。好奇心が強い、これから他の方法があります-活用できる他の注釈?
Pavan Dittakavi

0

私は試行錯誤をして、あなただけの両方のいずれかを使用する必要がある、という結論だ@XMLElementかを@XmlAccessorType(XmlAccessType.FIELD)

いつ使用するのですか?

ケース1:xmlファイルで使用するフィールド名と要素名が異なる場合は、使用する必要があります@XMLElement(name="elementName")。これにより、フィールドがその要素名にバインドされ、XMLファイルに表示されます。

ケース2:XMLのフィールド名とそれぞれの要素名が両方とも同じである場合、単純に使用できます@XmlAccessorType(XmlAccessType.FIELD)


0

多くの解決策が与えられており、内部には@Sriramと@ptomliも簡単に触れています。内部で何が起こっているのかを理解するために、ソースコードにいくつかの参照を追加したいだけです。

デフォルトでは(つまり@XmlRootElement、ルートクラス以外で使用される追加のアノテーションはありません)、JABXは次の2つの方法で公開されたものをマーシャリングしようとします。

  1. パブリックフィールド
  2. 規約に従って命名され、対応するセッターメソッドを持つゲッターメソッド

フィールドが(またはメソッドが返す)のnull場合、出力に書き込まれないことに注意してください。

これ@XmlElementを使用すると、非公開のもの(フィールドやゲッターメソッドなど)もマーシャリングできます。

しかし、2つの方法、つまりフィールドとゲッターメソッドは、互いに競合してはなりません。そうしないと、例外が発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.