We are using Jersey (Java REST library) for a project for the last few months and loving it. But this week have run into an issue with JAXB.
What I have is an element that has 2 children, each of them have children where some of their children reference each other.
Let me show some code.
Root root = new Root();
Parent parent1 = new Parent();
Parent parent2 = new Parent();
root.add(parent1);
root.add(parent2);
Child child1 = new Child();
Child child2 = new Child();
Child child3 = new Child();
parent1.add(child1);
parent1.add(child2);
parent2.add(child2);
parent2.add(child3);
So we have 1 root, 2 parents and 3 children.
If I send this up and down the JAXB path, I seem to get back 4 children.
Each Parent has their own copy of child2.
Is there anyway to get JAXB to serialise the relationship and show that both parent1 and parent2 point to the same object?
We only found this issue recently, when more complex elements were being transmitted.
If there is no way to get JAXB to do this (thats what I believe at the moment), does anyone have any suggestions of a way I could do some magic in Jersey to re-instate the relationship?
JAXB does support non-containment references between objects in the tree using a combination of @XmlID/@XmlIDREF. A requirement for this is that all objects in the tree must also be referenced by a containment relationship. In your model this might involve giving Root a collection of Child.
Below would be a modified version of your code:
Root root = new Root();
Parent parent1 = new Parent();
Parent parent2 = new Parent();
root.add(parent1);
root.add(parent2);
Child child1 = new Child();
child1.id = "1";
root.add(child1);
parent1.add(child1);
Child child2 = new Child();
child2.id = "2";
root.add(child2);
parent1.add(child2);
parent2.add(child2);
Child child3 = new Child();
child3.id = "3";
root.add(child3);
parent2.add(child3);
Then your model classes would look like:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Root {
public List<Parent> parent = new ArrayList<Parent>();
public List<Child> child = new ArrayList<Child>();
public void add(Parent parent1) {
parent.add(parent1);
}
public void add(Child child1) {
child.add(child1);
}
}
import javax.xml.bind.annotation.XmlIDREF;
public class Parent {
@XmlIDREF
public List<Child> child = new ArrayList<Child>();
public void add(Child child1) {
child.add(child1);
}
}
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlID;
public class Child {
@XmlID
@XmlAttribute
public String id;
}
The resulting XML would look like:
<root>
<parent>
<child>1</child>
<child>2</child>
</parent>
<parent>
<child>2</child>
<child>3</child>
</parent>
<child id="1"/>
<child id="2"/>
<child id="3"/>
</root>
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