So, I'm working on a RESTful data API with Java, Hibernate, JPA annotations, JAX-RS annotations, JAXB, Jersey annotations, and Jackson JSON parser.
After working through the various configurations of the MAPPING and NATURAL JSON notations that Jersey provides, I finally decided to use the Jackson JSON parser. Jackson would be perfect besides this one problem ...
The problem I ran into is that Jackson doesnβt work with JAXB annotations "@XmlID" and "@XmlIDREF", which I use to indicate relationships between entities and although "@JsonBackReference" and "@JsonManagedReference" help with by this. The combination seems to be destroyed when working with the direct properties of self-reference.
This seems to be a fairly common problem. How did any of you get around this Jackson restriction?
With my POJO how ...
@XmlRootElement
public class Employee implements Serializable {
private Date lastUpdatedOn;
private Employee lastUpdatedBy;
private Integer empId;
@JoinColumn(nullable=false)
@OneToOne
@XmlIDREF
public Employee getLastUpdatedBy() {
return createdBy;
}
public void setLastUpdatedBy(Employee lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
@Temporal(TemporalType.TIMESTAMP)
public Date getLastUpdatedOn() {
return createdOn;
}
public void setLastUpdatedOn(Date lastUpdatedOn) {
this.lastUpdatedOn = lastUpdatedOn;
}
@XmlID
@XmlJavaTypeAdapter(IntegerAdapter.class)
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
}
... and the next EmployeeResource ...
@Path("/Employees")
public class EmployeeResource {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
@GET
@Path("/{empId}")
public Response getEmployees(
@Context UriInfo ui
, @PathParam("id") Integer empId
) {
this.employees = HibernateUtil.pagedQuery(
Employee.class
, new ArrayList() {
Restrictions.eq("empId",empId)
}
);
return Response.ok(this).build();
}
}
My JAX-RS resource throws the following error:
org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle (through reference chain: resources.EmployeeResource["employees"]->java.util.ArrayList[0]->entities.Employee["lastUpdatedBy"])
... but I want him to create ...
{
"employees" : [ {
"lastUpdatedOn" : 1331149770737,
"lastUpdatedBy" : 10150,
"empId" : 10150,
} ],
}
Thanks in advance, everyone!
NOTES:
- I use IntegerAdapter.class to convert it to a string so that it works with the @XmlID annotation.
- The Employee and EmployeeResource classes described above are simply shorthand versions of my actual implementation, but they are part of my implementation that is related to this direct problem of self-reference.
β 1 2012.03.10
, , , , . , , .