简体   繁体   中英

JAXB abstract class and XmlID / XmlIDREF

Ok. I'm new to JAXB and im having some troubles with XmlID and XmlIDREF where the ID is in an abstract class.

Here is my problem:

Abstract class

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(EntityImpl.class)
public abstract class AbstractEntity {

    @XmlID
    private String id;

    public AbstractEntity() {
        this.id = generateStringId();
    }


    private static String generateStringId() {
        return "urn:uuid:" + UUID.randomUUID().toString();
    }
}

Implementing class

@XmlAccessorType(XmlAccessType.FIELD)
public class EntityImpl extends AbstractEntity {

    private String variabel_l = "1";
    private String variabel_2 = "2";
    private String variabel_3 = "3";
    private String variabel_4 = "4";
}

Some class

This class holds an AbstractEntity and in this example a String.

@XmlAccessorType(XmlAccessType.FIELD)
public class SomeClass {

    @XmlIDREF
    private AbstractEntity ae;
    private String status;

    private SomeClass() {
    }

    public SomeClass(AbstractEntity ae, String status) {
        this.ae= ae;
        this.status = status;
    }

}

Root

This class holds two lists, one list containing instances of "SomeClass" and one list containing instances of "EntityImpl"

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Root {

    @XmlElementWrapper
    @XmlElement(name = "result")
    private List<SomeClass> someClassList = new ArrayList<>();


    @XmlElementWrapper
    @XmlElement(name = "entityImpl")
    private List<EntityImpl> entityImplList = new ArrayList<>();

    public void addResult(SomeClass someClass) {
        this.someClassList.add(someClass);
    }

    public void addEntityImpl(EntityImpl EntityImpl) {
        this.entityImplList.add(EntityImpl);
    }

Demo-Code

impl is added to res, and both res and impl are added to their respective lists on root.

public static void main(String[] args) throws JAXBException {
    Root root = new Root();
    EntityImpl impl = new EntityImpl();

    SomeClass res = new SomeClass(impl, "something");
    root.addEntityImpl(impl);
    root.addResult(res);


    JAXBContext JAXB_CONTEXT;
    JAXB_CONTEXT = JAXBContext.newInstance(Root.class);

    StringWriter writer = new StringWriter();
    JAXB_CONTEXT.createMarshaller().marshal(root, writer);
    System.out.println(writer.getBuffer().toString());


    }

My desired result is a refrence to the Id of impl in the SomeClass-entity, but instead the result is this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <someClassList>
        <result>
            <ae xsi:type="entityImpl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <id>urn:uuid:b8a4c0e4-330d-4ed7-9b68-1517d2eb4c2a</id>
                <variabel_l>1</variabel_l>
                <variabel_2>2</variabel_2>
                <variabel_3>3</variabel_3>
                <variabel_4>4</variabel_4>
                <variabel_5>5</variabel_5>
            </ae>
            <status>something</status>
        </result>
    </someClassList>
    <entityImplList>
        <entityImpl>
            <id>urn:uuid:b8a4c0e4-330d-4ed7-9b68-1517d2eb4c2a</id>
            <variabel_l>1</variabel_l>
            <variabel_2>2</variabel_2>
            <variabel_3>3</variabel_3>
            <variabel_4>4</variabel_4>
            <variabel_5>5</variabel_5>
        </entityImpl>
    </entityImplList>
</root>

If i move the @XmlIDREF to the entityImplList in the root-entity then the referencing works fine and I get this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <someClassList>
        <result>
            <ae xsi:type="entityImpl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <id>urn:uuid:46d0681f-4ec6-49ac-8c22-4954eaa5c680</id>
                <variabel_l>1</variabel_l>
                <variabel_2>2</variabel_2>
                <variabel_3>3</variabel_3>
                <variabel_4>4</variabel_4>
                <variabel_5>5</variabel_5>
            </ae>
            <status>something</status>
        </result>
    </someClassList>
    <entityImplList>
        <entityImpl>urn:uuid:46d0681f-4ec6-49ac-8c22-4954eaa5c680</entityImpl>
    </entityImplList>
</root>

Is it possible to get the XmlID / XmlIDREF to work when the REF is in "SomeClass" or is this not possible?
Any ideas?

When I run the code exactly as you have it in your question I get the following, is this not what you are getting as output?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <someClassList>
        <result>
            <ae>urn:uuid:b34f3b9e-1086-4dfc-852f-4bc55b5d5a6e</ae>
            <status>something</status>
        </result>
    </someClassList>
    <entityImplList>
        <entityImpl>
            <id>urn:uuid:b34f3b9e-1086-4dfc-852f-4bc55b5d5a6e</id>
            <variabel_l>1</variabel_l>
            <variabel_2>2</variabel_2>
            <variabel_3>3</variabel_3>
            <variabel_4>4</variabel_4>
        </entityImpl>
    </entityImplList>
</root>

UPDATE

Based on investigation by myself and Ørjan Johansen there appears to be a bug related to this use case in the implementation of JAXB included in JDK 1.7.0_21 for Windows. The use case works correctly in JDK 1.7.0_21 for the Mac, and jdk1.6.0_45 for Windows. This use case also works correctly when EclipseLink MOXy is used as the JAXB (JSR-222) provider.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM