Tuesday, February 14, 2012

Unmarshalling returned null object from a successfully marshalled XML


i have the following classes which is marshalled as an XML




<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer id="100">
<age>21</age>
<hobbies>
<hobby>
<cost>sd</cost>
<name>na</name>
</hobby>
<hobby>
<cost>sd</cost>
<name>nb</name>
</hobby>
</hobbies>
<name>test</name>
</customer>



However, when i tried to unmarshall, I can only create the customer object but not hobby, which returns null Am i doing something wrong here? The problem seems to be with the XML hierarchy?




package com.mytest.jxb;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;

@XmlRootElement(name="customer")
@XmlSeeAlso({Hobby.class})
public class Customer {

String name;
int age;
int id;
@XmlElementRef
private List<Hobby> hobbyList = new ArrayList<Hobby>();

public Customer(){
//hobbyList = new ArrayList<Hobby>();
}

//@XmlElement
public String getName() {
return name;
}

@XmlElement
public void setName(String name) {
this.name = name;
}

//@XmlElement
public int getAge() {
return age;
}

@XmlElement
public void setAge(int age) {
this.age = age;
}
//@XmlAttribute
public int getId() {
return id;
}

@XmlAttribute
public void setId(int id) {
this.id = id;
}
public void addHobby(Hobby h) {
hobbyList.add(h);
}
@XmlElementWrapper(name="hobbies")
@XmlElement(name = "hobby")
public List<Hobby> getHobbies(){
return hobbyList;
}
}

package com.mytest.jxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
class Hobby {

private String name;
private String cost;

public Hobby(){
}

public Hobby(String name, String cost){
this.name = name;
this.cost = cost;
}
//@XmlElement
public void setName(){
this.name = name;
}
@XmlElement
public String getName(){
return name;
}
//@XmlElement
public void setCost(){
this.cost = cost;
}
@XmlElement
public String getCost(){
return cost;
}
}

1 comment:

  1. Having addHobby(Hobby h) is not enough for JAXB. Your class should be real POJO and should have void setHobbies(List<Hobby> hobbyList) { this.hobbyList = hobbyList; }. Also I think you can safely remove @XmlElementRef from hobbyList field.

    EDIT: I have checked your classes and created the version which works OK:

    package test;

    import java.util.ArrayList;
    import java.util.List;

    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementRef;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;

    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;

    @XmlRootElement(name = "customer")
    public class Customer {

    String name;
    int age;
    int id;

    private List<Hobby> hobbyList = new ArrayList<Hobby>();

    public Customer() {
    }

    @XmlElement
    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    @XmlElement
    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    @XmlAttribute
    public int getId() {
    return id;
    }

    public void setId(int id) {
    this.id = id;
    }

    public void addHobby(Hobby h) {
    hobbyList.add(h);
    }

    @XmlElementWrapper(name = "hobbies")
    @XmlElement(name = "hobby")
    public List<Hobby> getHobbies() {
    return hobbyList;
    }

    @Override
    public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
    }

    package test;

    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;

    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;

    @XmlRootElement
    class Hobby {

    private String name;
    private String cost;

    public Hobby() {
    }

    public Hobby(String name, String cost) {
    this.name = name;
    this.cost = cost;
    }

    public void setName(String name) {
    this.name = name;
    }

    @XmlElement
    public String getName() {
    return name;
    }

    public void setCost(String cost) {
    this.cost = cost;
    }

    @XmlElement
    public String getCost() {
    return cost;
    }

    @Override
    public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
    }

    ReplyDelete