Search code examples
javaxmljaxbmarshallingunmarshalling

JaxB Xml Can't find the reason for NullPointerException


i am trying to read an xml file with jaxb in java but for some reason while trying to access the product child elements i am geting a NullpointerException and i can't find a reason for why i am geting it unless my code is wrong somehow and jaxb does not correctly parse the tags in the xml file.Any help finding out why i am receiving NullPointer in this case it would be greatly appreciated.

this is the error

Exception in thread "main" java.lang.NullPointerException
    at App.main(App.java:18)

The line where this is thrown is here.Basically the products list is empty for some reason.

List<Product> products = order1.getProducts();
            System.out.println(products.size());

from here

 public static void main(String[] args) {
        Utils utils = new Utils();
        try {
            utils.marshall();
            Orders orders = utils.unMarshal();
            List<Order> order = orders.getOrder();
            Order order1 = order.get(0);
            List<Product> products = order1.getProducts();
            System.out.println(products.size());
            System.out.println(order.size());

        } catch (JAXBException exception) {
            exception.printStackTrace();
        }

now my xml file looks like this

<?xml version="1.0" encoding="UTF-8"?>
<orders>
    <order created='2012-07-12T15:29:33.000' ID='2343'>
        <product>
            <description>Sony 54.6" (Diag) Xbr Hx929 Internet Tv</description>
            <gtin>00027242816657</gtin>
            <price currency="USD">2999.99</price>
            <supplier>Sony</supplier>
        </product>
        <product>
            <description>Apple iPad 2 with Wi-Fi 16GB - iOS 5 - Black</description>
            <gtin>00885909464517</gtin>
            <price currency="USD">399.0</price>
            <supplier>Apple</supplier>
        </product>
        <product>
            <description>Sony NWZ-E464 8GB E Series Walkman Video MP3 Player Blue</description>
            <gtin>00027242831438</gtin>
            <price currency="USD">91.99</price>
            <supplier>Sony</supplier>
        </product>
    </order>
    <order created='2012-07-13T16:02:22.000' ID='2344'>
        <product>
            <description>Apple MacBook Air A 11.6" Mac OS X v10.7 Lion MacBook</description>
            <gtin>00885909464043</gtin>
            <price currency="USD">1149.0</price>
            <supplier>Apple</supplier>
        </product>
        <product>
            <description>Panasonic TC-L47E50 47" Smart TV Viera E50 Series LED HDTV</description>
            <gtin>00885170076471</gtin>
            <price currency="USD">999.99</price>
            <supplier>Panasonic</supplier>
        </product>
    </order>
</orders>

while my classes that i use look like this.

package model;


import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "orders")

public class Orders {

    private List<Order> order;

    public Orders() {
    }

    public Orders(List<Order> order) {
        this.order = order;
    }

    public List<Order> getOrder() {
        return order;
    }

    @XmlElement
    public void setOrder(List<Order> order) {
        this.order = order;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Order {
    @XmlAttribute(name = "ID")
    private int ID;
    @XmlAttribute
    @XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
    private LocalDateTime created;
    @XmlElementWrapper
    @XmlElement(name = "product")
    private List<Product> products;


    public Order() {
    }

    public Order(int ID, LocalDateTime created, List<Product> products) {
        this.ID = ID;
        this.created = created;
        this.products = products;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public LocalDateTime getCreated() {
        return created;
    }


    public void setCreated(LocalDateTime created) {
        this.created = created;
    }

    public List<Product> getProducts() {
        return products;
    }


    public void setProducts(List<Product> products) {
        this.products = products;
    }
}
public class Product {
        private String description;
        private long gtin;
        private BigDecimal price;
        private String supplier;

        public Product() {
        }

        public Product(String description, long gtin, BigDecimal price, String supplier) {
            this.description = description;
            this.gtin = gtin;
            this.price = price;
            this.supplier = supplier;
        }

        public String getDescription() {
            return description;
        }

        @XmlElement
        public void setDescription(String description) {
            this.description = description;
        }

        public long getGtin() {
            return gtin;
        }

        @XmlElement
        public void setGtin(long gtin) {
            this.gtin = gtin;
        }

        public BigDecimal getPrice() {
            return price;
        }

        @XmlElement
        public void setPrice(BigDecimal price) {
            this.price = price;
        }

        public String getSupplier() {
            return supplier;
        }

        @XmlElement
        public void setSupplier(String supplier) {
            this.supplier = supplier;
        }
    }

I am also using an Adapter for the LocalDateTime.If it is needed i can add that aswell. Thank you


Solution

  • As you are not using a wrapper element for the product list you need to remove the @XmlElementWrapper from the products field in the Order class

    @XmlElement(name = "product")
    private List<Product> products;