将XmlIDREF / XmlID与接口和泛化一起使用时,EclipseLink错误50035

时间:2013-02-17 13:22:45

标签: jaxb eclipselink moxy

我正在尝试@XmlIDREF参考方法。注释是:

 /**
   * getter for Attribute/List<Attribute> attributes
   * @return attributes
   */
  @XmlElementWrapper(name="attributes")
  @XmlElements({
    @XmlElement(name="Attribute", type=AttributeJaxbDao.class)
  })
  @XmlIDREF
  public List<Attribute> getAttributes() { 

导致错误消息:

javax.xml.bind.JAXBException: 
Exception Description: Since the property or field [attributes] is set as XmlIDREF, the target type of each XmlElement declared within the XmlElements list must have an XmlID property.  Please ensure the target type of XmlElement [Attribute] contains an XmlID property.
 - with linked exception:
[Exception [EclipseLink-50035] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JAXBException
Exception Description: Since the property or field [attributes] is set as XmlIDREF, the target type of each XmlElement declared within the XmlElements list must have an XmlID property.  Please ensure the target type of XmlElement [Attribute] contains an XmlID property.]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:832)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:143)

虽然AttributeJaxbDao有注释:

 /**
   * getter for xsd:string/String id
   * @return id
   */
  @XmlAttribute(name="id")  
  @XmlID
  public String getId() { 

“标准使用”@XmlIDREF / @XmlID有两点不同之处:

  1. AttributeJaxbDao是派生类 - 注释位于超类
  2. 属性是一个接口 - 该类型在@XmlElement注释中被特别命名为AttributeJaxbDao.class
  3. 为什么这种情况会出现错误? 会有解决方法吗?我想避免被迫不使用界面和泛化。

1 个答案:

答案 0 :(得分:2)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。

遗憾的是,有两个错误导致我们阻止此用例正常工作。

这些错误已在EclipseLink 2.4.2和2.5.0流中得到修复。这些流目前正在开发中,每晚构建可以从以下链接下载(从2013年2月22日开始):


完整示例

下面是一个比你问题中给出的模型稍微复杂一点的模型,我将用它来证明现在一切正常。

Foo类有两个类型List<Attribute>的属性,Attribute是一个接口。两者都注释为@XmlElements,其中包含指定具体类型的@XmlElement注释。 attributeRefs属性也使用@XmlIDREF注释。

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Foo {

    @XmlElementWrapper(name="Attributes")
    @XmlElements({
        @XmlElement(name="AttributeFoo", type=AttributeJaxbDao.class),
        @XmlElement(name="AttributeBar", type=AttributeJaxbDao2.class)
      })
    List<Attribute> attributes = new ArrayList<Attribute>();;


    @XmlElementWrapper(name="AttributeRefs")
    @XmlElements({
      @XmlElement(name="AttributeRefFoo", type=AttributeJaxbDao.class),
      @XmlElement(name="AttributeRefBar", type=AttributeJaxbDao2.class)
    })
    @XmlIDREF
    List<Attribute> attributeRefs = new ArrayList<Attribute>();

}

属性

Attribute只是一个非常简单的界面。

public interface Attribute {

}

AttributeJaxbDao

这是Attribute的一个实现,其中包含一个注释为@XmlID的字段,该字段将由@XmlIDREF注释利用。

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class AttributeJaxbDao implements Attribute {

    @XmlAttribute(name="id")  
    @XmlID
    String id;

    String name;

}

AttributeJaxbDao2

这也是Attribute的一个实现,其中有一个用@XmlID注释的字段。

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class AttributeJaxbDao2 implements Attribute {

    @XmlAttribute(name="id")  
    @XmlID
    String id;

    String name;

}

<强>演示

下面是一些可以运行的演示代码,以证明一切正常:

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14921547/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

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

}

input.xml中/输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
    <Attributes>
        <AttributeFoo id="a">
            <name>A</name>
        </AttributeFoo>
        <AttributeBar id="b">
            <name>B</name>
        </AttributeBar>
        <AttributeFoo id="c">
            <name>C</name>
        </AttributeFoo>
    </Attributes>
    <AttributeRefs>
        <AttributeRefFoo>a</AttributeRefFoo>
        <AttributeRefBar>b</AttributeRefBar>
        <AttributeRefFoo>c</AttributeRefFoo>
    </AttributeRefs>
</foo>