Как обойти неспособность Джексона обрабатывать прямые ссылки на самих себя в компонентах JPA

Итак, я работаю над API данных RESTful, используя Java, Hibernate, аннотации JPA, аннотации JAX-RS, аннотации JAXB, Jersey и парсер Jackson JSON.

Попробовав различные конфигурации нотаций MAPPING и NATURAL JSON, которые предоставляет Джерси, я, наконец, решил использовать парсер Jackson JSON. Джексон был бы идеальным, если бы не одна проблема...

Проблема, с которой я столкнулся, заключается в том, что Джексон не работает с аннотациями JAXB, "@XmlID" и "@XmlIDREF", которые я использую для обозначения отношений между сущностями. , и хотя в этом помогают "@JsonBackReference" и "@JsonManagedReference". Комбинация, похоже, не работает, когда речь идет о свойствах с прямой ссылкой на себя.

Похоже, это довольно распространенная проблема. Как кто-нибудь из вас обошел это ограничение с Джексоном?

С моим POJO as...

@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,
  } ],
}

Заранее всем спасибо!

ПРИМЕЧАНИЯ:

  1. Я использую класс IntegerAdapter.class для преобразования его в строку, чтобы он работал с аннотацией @XmlID.
  2. Классы Employee и EmployeeResource, описанные выше, являются просто сокращенными версиями моей фактической реализации, но они представляют часть моей реализации, имеющую отношение к этой прямой проблеме самоссылки.

РЕДАКТИРОВАТЬ №1 2012.03.10 Извините, в моей первой версии этого вопроса я запутался между версией, которую я использую в естественной нотации Джерси, и версией, которую я использую с Джексоном. Я пересмотрел свой вопрос, чтобы более точно отразить проблему прямой самореференции, которую я имею с Джексоном.

5
задан hypno7oad 11 March 2012 в 01:38
поделиться