2

JAXBのEclipseLink実装(2.3)を使用してPOJOをXMLにマップしていますが、次のユースケースで問題が発生しています。

public abstract class A {

    public abstract Set<X> getX();
    // There is no setter
}


public class B extends A {

    // Set via constructor
    private Set<X> x;

    @Override
    public Set<X> getX();

}

マッピング自体を外部バインディングファイルで完全に定義しています。クラスAを次のように一時的に設定します。

<java-type name="foo.A" xml-transient="true"/>

クラスBの場合:

<java-type name="bar.B" xml-accessor-type="PROPERTY">
    <xml-root-element name="B" />
    <java-attributes>
        <xml-element java-attribute="x" xml-path="..."/>
    </java-attributes>
</java-type>

さて、マーシャリングすると、例外が発生します。「[x]という名前の重複プロパティがクラス[bar.B]で見つかりました」。これは、私の意見では、Aの抽象宣言に由来し、Bに継承されています。

BのアクセサタイプをFIELDに設定すると、このエラーが解消されます。残念ながら、これはオプションではありません。Bには、フィールドではなく計算値を返すマーシャル用の追加のプロパティがあるため、PROPERTYでスタックします。 (以下の作業:BのアクセサータイプをFIELDに設定し、追加のプロパティを@XmlPathアノテーションでマッピングします-ただし、コードにアノテーションは必要ありません)。

クラスBのアクセサタイプのPROPERTYで立ち往生していたので、次の試みは次のとおりでした。

<java-type name="foo.A" xml-accessor-type="NONE"/>

抽象プロパティがBに継承されないようにするには、次のようにします。

Ignoring attribute [x] on class [bar.B] as no Property was generated for it.

このマッピングを使用しても同じことが起こります。

<java-type name="foo.A" xml-accessor-type="PROPERTY">
    <java-attributes>
        <xml-transient java-attribute="x"/>
    </java-attributes>
</java-type>

どちらの場合も、プロパティ'x'は無視されます。

私は今これにかなりの時間を費やしてきました-これを機能させることが不可能だとは想像できませんか?

現時点での私の回避策:

foo.Aを一時的なものとして残し、bar.BにアクセサータイプのFIELDを指定して(問題なくプロパティ'x'を取得します)、コードの注釈を使用してBの追加のプロパティをマッピングします。しかし、前に述べたように、私はこれを注釈なしで完全に解決したいと思います-誰かアイデアはありますか?ブレイズ?:)

よろしく、

--qu

4

1 に答える 1

1

注: 私はEclipseLink JAXB(MOXy)のリーダーであり、JAXB 2(JSR-222)エキスパートグループのメンバーです。

バグが発生したようです。次のリンクで、この問題の進捗状況を追跡できます。この問題に関する追加の詳細を以下に示します。


注釈の使用

このユースケースをJAXB/MOXyアノテーションでマッピングする場合は@XmlAccessorType(XmlAccessType.NONE)Aクラスに設定して次のようにすることができます。

A

package forum8727402;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.NONE)
public abstract class A {

    public abstract String getX();

}

B

package forum8727402;

import javax.xml.bind.annotation.*;    
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
public class B extends A {

    @XmlPath("a/b/c/text()")
    private String x;

    public B() {
        x = "Hello World";
    }

    @Override
    public String getX() {
        return x;
    }

    @XmlElement
    public String getCalculatedValue() {
        return "Calculated Value";
    }

}

デモ

package forum8727402;

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(B.class);

        B b = new B();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(b, System.out);
    }

}

出力

<?xml version="1.0" encoding="UTF-8"?>
<b>
   <a>
      <b>
         <c>Hello World</c>
      </b>
   </a>
   <calculatedValue>Calculated Value</calculatedValue>
</b>

MOXyの外部マッピングファイルの使用

oxm.xml

以下は、前に示した注釈と同等のものを表すMOXy外部マッピングファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum8727402">
    <java-types>
        <java-type name="A" xml-accessor-type="NONE"/>
        <java-type name="B">
            <xml-root-element/>
            <java-attributes>
                <xml-element java-attribute="x" xml-path="a/b/c/text()"/>
                <xml-element java-attribute="calculatedValue"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

デモ

以下のコードは、マッピングファイルを参照する方法を示しています。

package forum8727402;

import java.util.*;
import javax.xml.bind.*;    
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum8727402/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {A.class, B.class}, properties);

        B b = new B();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(b, System.out);
    }

}

出力

[EL Warning]: 2012-01-04 14:45:46.366--Ignoring attribute [x] on class [forum8727402.xml.B] as no Property was generated for it.
<?xml version="1.0" encoding="UTF-8"?>
<b>
   <calculatedValue>Calculated Value</calculatedValue>
</b>
于 2012-01-04T19:52:38.913 に答える