The code below used to work under the JAXB implementation used by JDK 1.7, but now under JDK 1.8 it\'s broken. In the code below you will find the key change that seems to
When a collection property is mapped in JAXB it first checks the getter to see if the collection property has been pre-initialized. In the example below I want to have my property exposed as List<String>
, but have the backing implementation be a LinkedList
ready to hold 1000 items.
private List<String> foos = new LinkedList<String>(1000);
@XmlElement(name="foo")
public List<String> getFoos() {
return foos;
}
If you previously had JAXB call the setter on a property mapped to a collection that returned a non-null response from the getter, then there was a bug in that JAXB implementation. Your code should not have worked in the previous version either.
To have the setter called you just need to have your getter return null, on a new instance of the object. Your code could look something like:
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "Foo")
public class Foo {
private List<CustomObject> list = null;
@XmlElementWrapper(name = "Wrap")
@XmlElement(name = "Item", required = true)
public synchronized void setList(List<CustomObject> values) {
if (null == list) {
list = new ArrayList<CustomObject>();
} else {
list.clear();
}
list.addAll(values);
}
public synchronized List<CustomObject> getList() {
if (null == list) {
return null;
}
return new ArrayList(list);
}
}
If you don't need to perform any logic on the List returned from JAXB's unmarshalling then using field access may be an acceptable solution.
@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
@XmlElementWrapper(name = "Wrap")
@XmlElement(name = "Item", required = true)
private List<CustomObject> list = null;
public synchronized void setList(List<CustomObject> values) {
if(null == list) {
list = new ArrayList<CustomObject>();
} else {
list.clear();
}
list.addAll(values);
}
public synchronized List<CustomObject> getList() {
return new ArrayList(list);
}
}