| Summary: | Problem using @XmlJavaTypeAdapter with @XmlElementRef | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Blaise Doughan <blaise.doughan> | ||||||||
| Component: | Eclipselink | Assignee: | Nobody - feel free to take it <nobody> | ||||||||
| Status: | RESOLVED FIXED | QA Contact: | |||||||||
| Severity: | normal | ||||||||||
| Priority: | P3 | CC: | david.mccann | ||||||||
| Version: | unspecified | ||||||||||
| Target Milestone: | --- | ||||||||||
| Hardware: | PC | ||||||||||
| OS: | Windows XP | ||||||||||
| Whiteboard: | |||||||||||
| Bug Depends on: | |||||||||||
| Bug Blocks: | 327593 | ||||||||||
| Attachments: |
|
||||||||||
Created attachment 185172 [details]
Code demonstrating the bug
Created attachment 185551 [details]
Proposed fix
Created attachment 185552 [details]
Supporting tests
Reviewed by: matt.macivor@oracle.com Tests: all unit tests pass as expected; jaxb.xmladapter.xmlelementref.XmlAdapterElementRefTestCases; jaxb.xmladapter.xmlelementref.XmlAdapterElementRefListTestCases Revision: 8732 The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
The following example should produce the following XML: <transactionAdd> <salesOrderAdd/> </transactionAdd> Instead of: <transactionAdd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <txnType xsi:type="invoiceAdd"/> </transactionAdd> EXAMPLE On the txnType property we will use a combination of @XmlJavaTypeAdapter and @XmlElementRef: import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement public class TransactionAdd { private String txnType; @XmlJavaTypeAdapter(MyAdapter.class) @XmlElementRef public String getTxnType() { return txnType; } public void setTxnType(String txnType) { this.txnType = txnType; } } The adapted objects will look like: import javax.xml.bind.annotation.XmlSeeAlso; @XmlSeeAlso({InvoiceAdd.class, SalesOrderAdd.class}) public class AbstractAdd { } --- import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class InvoiceAdd extends AbstractAdd { } --- SalesOrderAdd import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class SalesOrderAdd extends AbstractAdd { } The XmlAdapter to convert between the String and the adapted objects will look like: import javax.xml.bind.annotation.adapters.XmlAdapter; public class MyAdapter extends XmlAdapter<AbstractAdd, String> { @Override public String unmarshal(AbstractAdd v) throws Exception { if(v instanceof SalesOrderAdd) { return "salesOrderAdd"; } return "invoiceAdd"; } @Override public AbstractAdd marshal(String v) throws Exception { if("salesOrderAdd".equals(v)) { return new SalesOrderAdd(); } return new InvoiceAdd(); } } The following demo code can be used: import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(TransactionAdd.class); File xml = new File("input.xml"); Unmarshaller unmarshaller = jc.createUnmarshaller(); TransactionAdd ta = (TransactionAdd) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(ta, System.out); } } For more information see: - http://stackoverflow.com/questions/4441692/jaxb-element-name-based-on-object-property/4441822#4441822