Como contornar a incapacidade de Jackson de lidar com auto-referências diretas em beans JPA
ntão, eu estou trabalhando em uma API de dados RESTful usando anotações Java, Hibernate, JPA, anotações JAX-RS, anotações JAXB, Jersey e o analisador Jackson JSO
Depois de tentar várias configurações das notações MAPPING e NATURAL JSON fornecidas por Jersey, finalmente decidi usar o analisador Jackson JSON. Jackson seria perfeito, exceto por esta edição ...
O problema que me deparei é que Jackson não trabalha com as anotações JAXB, "@XmlID" e "@XmlIDREF", que eu uso para significar meus relacionamentos de entidade e, embora a ajuda "@JsonBackReference" e "@JsonManagedReference" com isso. A combinação parece quebrar ao lidar com propriedades de auto-referência diret
Parece que isso seria um problema bastante comum. Como alguns de vocês contornaram essa limitação com Jackson?
Com meu POJO como ...
@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;
}
}
... e o seguinte 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();
}
}
Meu recurso JAX-RS produzirá o seguinte erro
org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle (through reference chain: resources.EmployeeResource["employees"]->java.util.ArrayList[0]->entities.Employee["lastUpdatedBy"])
... mas quero que produza ...
{
"employees" : [ {
"lastUpdatedOn" : 1331149770737,
"lastUpdatedBy" : 10150,
"empId" : 10150,
} ],
}
Agradecemos antecipadamente a todos!
NOTAS
Use o IntegerAdapter.class para convertê-lo em uma sequência de caracteres para que ele funcione com a anotação @XmlIs classes Employee e EmployeeResource descritas acima são apenas versões abreviadas da minha implementação real, mas representam a parte da minha implementação que é relevante para esse problema de auto-referência diretEDIT # 1 2012.03.10 Sinto muito, na minha primeira versão desta pergunta, fiquei confuso entre a versão que utilizei a notação natural de Jersey versus a versão que tenho em execução com Jackson. Revisei minha pergunta para refletir com mais precisão o problema de auto-referência direta que tenho com Jackson.