When trying to map a customer-> order 1:n relationship with jaxb 2.2.6 I'd like to get the list of orders wrapped in a separate node "orders".
currently the result is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer>
<id>100</id>
<name>John Doe</name>
<orders>
<address>100 main street, smalltown, pa</address>
<orderid>1100</orderid>
</orders>
<orders>
<address>5 broadway, ny, ny</address>
<orderid>1200</orderid>
</orders>
</Customer>
but I'd like to get:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer>
<id>100</id>
<name>John Doe</name>
<orders>
<order>
<address>100 main street, smalltown, pa</address>
<orderid>1100</orderid>
</order>
<order>
<address>5 broadway, ny, ny</address>
<orderid>1200</orderid>
</order>
</orders>
</Customer>
What needs to be changed to get this result?
The relevant source code has:
and uses this jaxb implementation:
<!-- JAXB -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.6</version>
</dependency>
Customer interface:
/**
* Copyright (C) 2011-2012 BITPlan GmbH
*
* http://www.bitplan.com
*
* generated: 2012-10-15 15:12 with smartGENERATOR
*/
package com.bitplan.testentity;
import java.util.List;
import com.bitplan.testentity.Order;
/**
* interface for Customer
*/
public interface Customer {
// >>>{interface}{Customer}{Customer}
// no implementation yet !!!
// <<<{interface}{Customer}{Customer}
/**
* getter for name
* @return name
*/
public String getName();
/**
* setter for name
* @param pname - new value for name
*/
public void setName(String pname);
/**
* getter for id
* @return id
*/
public long getId();
/**
* setter for id
* @param pid - new value for id
*/
public void setId(long pid);
/**
* getter for orders
* @return orders
*/
public List<Order> getOrders();
/**
* setter for orders
* @param porders - new value for orders
*/
public void setOrders(List<Order> porders);
} // Customer
Order interface:
/**
* Copyright (C) 2011-2012 BITPlan GmbH
*
* http://www.bitplan.com
*
* generated: 2012-10-15 at 23:59 with smartGENERATOR
*/
package com.bitplan.testentity;
/**
* interface for Order
*/
public interface Order {
// >>>{interface}{Order}{Order}
// no implementation yet !!!
// <<<{interface}{Order}{Order}
/**
* getter for orderid
* @return orderid
*/
public long getOrderid();
/**
* setter for orderid
* @param porderid - new value for orderid
*/
public void setOrderid(long porderid);
/**
* getter for shipping address
* @return address
*/
public String getAddress();
/**
* setter for shipping address
* @param paddress - new value for shipping address
*/
public void setAddress(String paddress);
} // Order
CustomerJaxbDao implementation
/**
* Copyright (C) 2011-2012 BITPlan GmbH
*
* http://www.bitplan.com
*
* generated: 2012-10-15 at 23:51 with smartGENERATOR
*/
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Order;
import com.bitplan.testentity.Customer;
import java.util.List;
import java.util.ArrayList;
/**
* JaxB Data access object for Customer
* Entity: Customer for container testentity
* Table: Customer
*/
@XmlRootElement(name="Customer")
public class CustomerJaxbDao implements Customer {
/**
* name
*/
private String name;
/**
* id
*/
private long id;
/**
* orders
*/
private List<Order> orders=new ArrayList<Order>();
/**
* getter for name
* @return name
*/
@XmlElement(name="name")
public String getName() { return name; };
/**
* setter for name
* @param pname - new value for name
*/
public void setName(String pname) { name=pname; };
/**
* getter for id
* @return id
*/
@XmlElement(name="id")
public long getId() { return id; };
/**
* setter for id
* @param pid - new value for id
*/
public void setId(long pid) { id=pid; };
/**
* getter for orders
* @return orders
*/
@XmlElement(name="orders", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
/**
* setter for orders
* @param porders - new value for orders
*/
public void setOrders(List<Order> porders) { orders=porders; };
} // CustomerJaxbDao
OrderJaxbDao implementation
/**
* Copyright (C) 2011-2012 BITPlan GmbH
*
* http://www.bitplan.com
*
* generated: 2012-10-15 with smartGENERATOR
*/
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Order;
/**
* JaxB Data access object for Order
* Entity: Order for container testentity
* Table: Order
*/
@XmlRootElement(name="Order")
public class OrderJaxbDao implements Order {
/**
* orderid
*/
private long orderid;
/**
* shipping address
*/
private String address;
/**
* getter for orderid
* @return orderid
*/
@XmlElement(name="orderid")
public long getOrderid() { return orderid; };
/**
* setter for orderid
* @param porderid - new value for orderid
*/
public void setOrderid(long porderid) { orderid=porderid; };
/**
* getter for shipping address
* @return address
*/
@XmlElement(name="address")
public String getAddress() { return address; };
/**
* setter for shipping address
* @param paddress - new value for shipping address
*/
public void setAddress(String paddress) { address=paddress; };
} // OrderJaxbDao
TestCustomerWrite Junit4 Testcase
package com.bitplan.storage.jaxb;
import static org.junit.Assert.*;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.junit.Test;
import com.bitplan.testentity.Customer;
import com.bitplan.testentity.Order;
import com.bitplan.testentity.jaxb.CustomerJaxbDao;
import com.bitplan.testentity.jaxb.OrderJaxbDao;
/**
*
* @author wf
*
*/
public class TestCustomerWrite {
@Test
public void test() throws JAXBException {
Customer customer=new CustomerJaxbDao();
customer.setId(100);
customer.setName("John Doe");
long orderid=1000;
String[] addresses={"100 main street, smalltown, pa","5 broadway, ny, ny"};
for (String address:addresses) {
Order order=new OrderJaxbDao();
order.setAddress(address);
order.setOrderid(orderid+=100);
customer.getOrders().add(order);
}
JAXBContext jaxbContext = JAXBContext.newInstance(CustomerJaxbDao.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter sw=new StringWriter();
jaxbMarshaller.marshal(customer, sw);
System.out.println(sw);
}
}
Instead of
/**
* getter for orders
* @return orders
*/
@XmlElement(name="orders", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
You need
/**
* getter for orders
* @return orders
*/
@XmlElement(name="order", type=OrderJaxbDao.class)
@XmlElementWrapper(name="orders")
public List<Order> getOrders() { return orders; };
The @XmlElementWrapper
name is the name of the wrapping element (orders) and the @XmlElement
name is the name of the per-entry element inside the wrapper (order).
This seems to do the trick:
@XmlElementWrapper(name="orders")
@XmlElement(name="order", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
improved CustomerJaxbDao
/**
* Copyright (C) 2011-2012 BITPlan GmbH
*
* http://www.bitplan.com
*
* generated: 2012-10-16 12:20 with smartGENERATOR
*/
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Customer;
import java.util.List;
import com.bitplan.testentity.Order;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.ArrayList;
/**
* JaxB Data access object for Customer
* Entity: Customer for container testentity
* Table: Customer
*/
@XmlRootElement(name="Customer")
public class CustomerJaxbDao implements Customer {
/**
* name
*/
private String name;
/**
* id
*/
private long id;
/**
* orders
*/
private List<Order> orders=new ArrayList<Order>();
/**
* getter for name
* @return name
*/
@XmlElement(name="name")
public String getName() { return name; };
/**
* setter for name
* @param pname - new value for name
*/
public void setName(String pname) { name=pname; };
/**
* getter for id
* @return id
*/
@XmlElement(name="id")
public long getId() { return id; };
/**
* setter for id
* @param pid - new value for id
*/
public void setId(long pid) { id=pid; };
/**
* getter for orders
* @return orders
*/
@XmlElementWrapper(name="orders")
@XmlElement(name="order", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
/**
* setter for orders
* @param porders - new value for orders
*/
public void setOrders(List<Order> porders) { orders=porders; };
} // CustomerJaxbDao
It sounds like you want to wrap the Order in your CustomerJaxbDao
class.
@XmlElementWrapper( name="orders" )
@XmlElement(name="order", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };
Might do what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With