Java 如何绕过杰克逊';无法处理JPA bean中的直接自引用

Java 如何绕过杰克逊';无法处理JPA bean中的直接自引用,java,jaxb,jersey,jax-rs,jackson,Java,Jaxb,Jersey,Jax Rs,Jackson,因此,我正在使用Java、Hibernate、JPA注释、JAX-RS注释、JAXB注释、Jersey和Jackson JSON解析器开发RESTful数据API 在尝试了Jersey提供的映射和自然JSON符号的各种配置之后,我最终决定改用Jackson JSON解析器。杰克逊会是完美的,除了这个问题 我遇到的问题是Jackson不使用JAXB注释“@XmlID”和“@XmlIDREF”,我用它们来表示我的实体关系,尽管“@JsonBackReference”和“@JsonManagedRef

因此,我正在使用Java、Hibernate、JPA注释、JAX-RS注释、JAXB注释、Jersey和Jackson JSON解析器开发RESTful数据API

在尝试了Jersey提供的映射和自然JSON符号的各种配置之后,我最终决定改用Jackson JSON解析器。杰克逊会是完美的,除了这个问题

我遇到的问题是Jackson不使用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;
    }
}
。。。以及以下员工资源

@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();
  }
}
。。。但我想让它产生

{
  "employees" : [ {
    "lastUpdatedOn" : 1331149770737,
    "lastUpdatedBy" : 10150,
    "empId" : 10150,
  } ],
}
提前谢谢大家

注:

  • 我使用IntegerAdapter.class将其转换为字符串,以便它与@XmlID注释一起使用
  • 上面描述的Employee和EmployeeResource类只是我实际实现的缩写版本,但它们代表了我的实现中与此直接自引用问题相关的部分
  • 编辑#1 2012.03.10
    很抱歉,在我的第一个问题版本中,我混淆了使用Jersey的自然符号的版本和与Jackson一起运行的版本。我已经修改了我的问题,以更准确地反映我与Jackson之间的直接自引用问题。

    Jackson 1.x不支持解析循环引用,但支持处理父/子样式依赖关系:博客条目有更多信息

    Jackson 2.0将使用新的
    @JsonIdentityInfo
    注释支持任意对象Id/引用处理,因此可能可以使用它来解决问题。官方的2.0版本还没有发布,但候选版本(最新版本是RC2)已经发布了,以防您想看一看。不确定它是否能解决你的问题,但也许会有帮助


    编辑:实际上,Jackson JAXB注释模块将支持2.0.0版的
    @XmlID
    /
    @XmlIDREF
    ——这是刚刚实现的,请参见。

    我认为您的问题与
    @XmlID
    没有关系,而是与JSON基础知识相关。JSON不支持类型,因此
    “10150”
    (字符串)和
    10150
    (整数,但不受支持)是“相同的”。我不同意这种说法。JSON理解对象、数组、字符串和数字等类型,www.JSON.org。对不起,我错了。我相信您需要的是从
    Date
    int
    的转换器。参见示例。抱歉@dma_k,我在写问题时感到困惑。我试着回到过去,说得更具体一些。起初我只是使用Jersey的自然注释,它不能很好地处理日期。现在我使用Jackson,所有字符串、日期(时间戳)和数字都已正确序列化。但是,我现在遇到了这个直接自引用问题,当Jersey使用JAXB注释“@XmlID”和“@XmlIDREF”时,这不是一个问题。谢谢链接。我来看看RC2。虽然他们不能像Jersey那样使用JAXB注释有点令人失望。JAXB注释是特定于XML的,所以对于Jackson来说它们是次要的——受支持,但必须适合通过本机机制工作。FWIW,现在有这样一个:[跟踪实现JAXB注释的可能性…如何调试
    @XmlIDREF
    注释是否到位?在我的代码中,它跳到,它只是序列化字段的内容,而不使用引用元素的ID。
    {
      "employees" : [ {
        "lastUpdatedOn" : 1331149770737,
        "lastUpdatedBy" : 10150,
        "empId" : 10150,
      } ],
    }