I am using Hibernate and RESTeasy, i try to avoid a cycle with these entities, as i have a OneToMany (ManyToOne) bidirectionnal relation between Artiste and Oeuvre entities :
Oeuvre.java
import javax.persistence.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@XmlRootElement(name = "oeuvre")
public abstract class Oeuvre {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Embedded
private Dimension dimension;
@XmlElement(defaultValue = "true")
private boolean hasBeenReproduced;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name = "artiste_id")
@XmlIDREF
private Artiste artiste;
@XmlElement
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// @XmlTransient
@XmlInverseReference(mappedBy = "oeuvres")
public Artiste getArtiste() {
return artiste;
}
public void setArtiste(Artiste artiste) {
this.artiste = artiste;
artiste.addOeuvre(this);
}
}
Personne.java
import javax.persistence.*;
import javax.xml.bind.annotation.XmlID;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Personne {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@XmlID
private int id;
}
Artiste.java
import java.util.*;
import javax.persistence.*;
import javax.xml.bind.annotation.*;
@Entity
@XmlRootElement(name = "artiste")
public class Artiste extends Personne {
private String bibliographie;
@OneToMany(mappedBy = "artiste", orphanRemoval = true, cascade = {
CascadeType.PERSIST, CascadeType.REMOVE })
private List<Oeuvre> oeuvres = new ArrayList<Oeuvre>();
@XmlElement
public List<Oeuvre> getOeuvres() {
return oeuvres;
}
public void setOeuvres(List<Oeuvre> oeuvres) {
this.oeuvres = oeuvres;
}
}
So i decided to use MOXy,
Here is my POM
<repository>
<id>EclipseLink</id>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
</repository>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy </artifactId>
<version>2.3.2</version>
</dependency>
nb : i would like to only have org.eclipse.persistence.moxy-2.3.2.jar as i am using hibernate (i don’t want eclipseLink), but i also have 3 other jars (including the core)
Then i put a jaxb.properties file in the package of my entities :
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
And added @XmlInverseReference(mappedBy=”oeuvres”) to getArtiste() instead od @XmlTranscient
==> i don’t have cycle anymore (like xmlTranscient) but i still don’t have any back pointer.
Then i added @XmlID & @XmlIDREF, the id of the artist is now represented in the xml result of a work of art BUT it doesn’t have the good value (0 but shoud be something else)
<Oeuvre>
<hasBeenReproduced>false</hasBeenReproduced>
<artiste>0</artiste>
<year>2010</year>
<id>2</id>
<titre>La joconde</titre>
</Oeuvre>
What am i doing wrong ? Thx in advance
EDIT :
Ok i have the following output using @XmlInverseReference when i marshall an “Artiste” Object :
<artiste>
<id>1</id>
<nom>a</nom>
<prenom>b</prenom>
<oeuvres>
<hasBeenReproduced>false</hasBeenReproduced>
<year>2010</year>
<id>25</id>
<titre>La joconde</titre>
</oeuvres>
</artiste>
According to your example this is the correct behaviour.
So if i understand well, it’s not possible to have a reference of the artiste id in the “Oeuvre” output (given above). We can’t retrieve the artist from a work of art.
In my case i don’t have to use @XmlID ?
Thx for your complete answer Blaise Doughan, it is much appreciated
Note: I’m the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
Below is a simplified example of how to use MOXy’s
@XmlInverseReferenceextension.Foo
Foois the root object for this example.Bar
Baris a child object. We use the@XmlInverseReferenceannotation to populate thefoofield with a reference to the parent object.jaxb.properties
To specify MOXy as your JAXB provider you need to include a file called
jaxb.propertieswith the following entry:input.xml
Demo
The following demo code will unmarshal the XML, check the back pointer and then marshal the objects back to XML.
Output
Below is the output of running the demo code. Node how the back pointer is populated correctly.
MOXy and Maven
You can use the following in your
pom.xmlfile to pull in MOXy.For some example POM files that pull in MOXy check out the examples I have hosted on GitHub:
UPDATE
Below I’ve provided an alternate mapping that uses
@XmlID/@XmlIDREFinstead of@XmlInverseReference.Foo
Bar
input.xml
For More Information