Итак, я работаю над API данных RESTful, используя Java, Hibernate, JPA-аннотации, JAX-RS-аннотации, JAXB-аннотации, Jersey и анализатор JSON JSON.
Попробовав различные конфигурации нотаций MAPPING и NATURAL JSON, которые предоставляет Джерси, я наконец решил вместо этого использовать парсер JSON Джексона. Джексон был бы идеален, если бы не этот выпуск ...
Проблема, с которой я столкнулся, заключается в том, что Джексон не работает с аннотациями JAXB, "@XmlID" и "@XmlIDREF", которые я использую для обозначения отношений между сущностями, и хотя "@JsonBackReference" и "@JsonManagedReference помогите с этим. Комбинация, кажется, ломается, когда имеешь дело с прямыми ссылочными свойствами.
Кажется, это будет довольно распространенная проблема. Как кто-нибудь из вас обошел это ограничение с Джексоном?
С моим POJO как ...
@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;
}
}
... и следующий 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();
}
}
Мой ресурс JAX-RS выдаст следующую ошибку
org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle (through reference chain: resources.EmployeeResource["employees"]->java.util.ArrayList[0]->entities.Employee["lastUpdatedBy"])
... но я хочу, чтобы это произвело ...
{
"employees" : [ {
"lastUpdatedOn" : 1331149770737,
"lastUpdatedBy" : 10150,
"empId" : 10150,
} ],
}
Спасибо всем заранее!
ПРИМЕЧАНИЯ:
- Я использую IntegerAdapter.class, чтобы преобразовать его в строку, чтобы он работал с аннотацией @XmlID.
- Классы Employee и EmployeeResource, описанные выше, являются просто сокращенными версиями моей фактической реализации, но они представляют ту часть моей реализации, которая имеет отношение к этой проблеме прямой самоссылки.
РЕДАКТИРОВАТЬ # 1 2012.03.10
Извините, в моей первой версии этого вопроса я запутался между версией, которую я использую, используя естественную запись Джерси, и версией, которую я использовал с Джексоном. Я пересмотрел свой вопрос, чтобы более точно отразить проблему прямой самореференции, которую я имею с Джексоном.