JAXB映射对XML的循环引用

我有一个包含循环的对象图。 如何让JAXB处理这个问题? 我尝试在子类中使用@XmlTransient注释,但JAXB marshaller仍然检测到循环。

 @Entity @XmlRootElement public class Contact { @Id private Long contactId; @OneToMany(mappedBy = "contact") private List addresses; ... } @Entity @XmlRootElement public class ContactAddress { @Id private Long contactAddressId; @ManyToOne @JoinColumn(name = "contact_id") private Contact contact; private String address; ... } 

使用JAXB的好处在于它是一个具有多个实现的标准运行时(就像JPA一样)。

如果您使用EclipseLink JAXB(MOXy),那么您可以使用许多扩展来处理JPA实体,包括双向关系。 这是使用MOXy @XmlInverseReference批注完成的。 它与marshal上的@XmlTransient类似,并在unmarshal上填充目标到源的关系。

http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/Relationships

 @Entity @XmlRootElement public class Contact { @Id private Long contactId; @OneToMany(mappedBy = "contact") private List addresses; ... } @Entity @XmlRootElement public class ContactAddress { @Id private Long contactAddressId; @ManyToOne @JoinColumn(name = "contact_id") @XmlInverseReference(mappedBy="addresses") private Contact contact; private String address; ... } 

其他扩展可用,包括支持复合键和嵌入式键类。

要指定EcliseLink MOXy JAXB实现,您需要在模型类(即Contract)中包含一个jaxb.properties文件,并带有以下条目:

 javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

“非官方JAXB指南”中的这个页面提供了三种处理周期的策略。 它们(摘要):

  • 将形成循环的参考属性之一标记为@XmlTransient。
  • 使用@XmlID和@XmlIDREF,以便使用XML ID表示引用,而不是使用包含。
  • 使用CycleRecoverable接口以编程方式处理周期。

XMLTransient几乎总是适用于周期。 您可能在字段级别具有XMLTransient,但尚未将XMLAccessorType指定为XmlAccessType.Field。 如果您没有指定任何内容,则默认值为XmlAccessType.Property – 或者您的getter。 我经历过Jaxb从类中获取xml元素,我错过了访问者类型注释,并且仍然可以正常工作。

只需看看本教程:通过jaxb 映射对XML的循环引用

我用它,效果很好:)

我们也可以使用XStream库,我尝试了一个项目,其中JAXB给出了循环错误,但XStream成功处理了它