Home > database >  JAXB Deserialization to object return null
JAXB Deserialization to object return null

Time:07-03

I need to transform the XML below to a POJO. I cannot modify the XML. My problem is the upsert object is always null.

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<MarginCall xmlns="http://my-name-space" type="Upsert">
    <upsert>
        <AccountId>ABCD</AccountId>
    </upsert>
</MarginCall>

MarginCall Class

@XmlRootElement(name="MarginCall", namespace="http://my-name-space")
@XmlAccessorType(XmlAccessType.FIELD)
public class MarginCall {

    @XmlAttribute
    private String type;
    @XmlElement
    protected Upsert upsert;

// Getters, setters and ToString()

Upsert Class

@XmlType(name = "upsert", namespace="")
@XmlAccessorType(XmlAccessType.FIELD)
public class Upsert {
    @XmlElement(name="AccountId")
    private String accountId;

// Getter, setter and ToString()

How I transform the XML (received as String:message below)

    JAXBContext jaxbContext;
    
    jaxbContext = JAXBContext.newInstance(new Class[]{com.sandrew.MarginCall.class});
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    
    MarginCall marginCall = (MarginCall) jaxbUnmarshaller.unmarshal(new StringReader(message));
    
    System.out.println(marginCall); // prints: MarginCall{type='Upsert', upsert=null}  <---- PROBLEM

I tried to change, remove the namespace on Upsert, without luck. I have also created a MarginCall object, then tried to write it as an XML, and confirmed the result is structured as I want:

Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
Upsert upsert = new Upsert();
upsert.setAccountId("ABCD");
MarginCall m = new MarginCall();
m.setType("T");
m.setUpsert(upsert);
jaxbMarshaller.marshal(m, new File("res.xml"));

// res.xml = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:MarginCall xmlns:ns2="http://my-name-space" type="T"><upsert><AccountId>ABCD</AccountId></upsert></ns2:MarginCall>

Any idea why when I go from String to POJO, I get null on the upsert object ?

CodePudding user response:

In XML the namespace definition xmlns="http://my-name-space" in the root element implicitly inherits to the nested elements. However, in Java this implicit inheriting is not the case. You need to code this explicitly. Therefore you need to specify this namespace also for the properties representing the non-root elements. You do this by specifying the namespace in their @XmlElement annotations.

In class MarginCall

@XmlElement(namespace="http://my-name-space")
protected Upsert upsert;

In class Upsert

@XmlElement(name="AccountId", namespace="http://my-name-space")
private String accountId;

After having done this, the output of the unmarshalled object will be

MarginCall(type=Upsert, upsert=Upsert(accountId=ABCD))
  • Related