Skip to main content

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;

}

}




Comments

  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

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...