我有一个包含循环的对象图。我如何让JAXB来处理这个问题?我尝试在子类中使用@XmlTransient
注释,但JAXB编组程序仍然检测到循环。
@Entity
@XmlRootElement
public class Contact {
@Id
private Long contactId;
@OneToMany(mappedBy = "contact")
private List<ContactAddress> addresses;
...
}
@Entity
@XmlRootElement
public class ContactAddress {
@Id
private Long contactAddressId;
@ManyToOne
@JoinColumn(name = "contact_id")
private Contact contact;
private String address;
...
}
答案 0 :(得分:17)
This page提供了三种处理周期的策略。它们(摘要):
答案 1 :(得分:12)
使用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<ContactAddress> 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
答案 2 :(得分:6)
XMLTransient几乎总是适用于周期。您可能在字段级别上具有XMLTransient,但尚未将XMLAccessorType指定为XmlAccessType.Field。如果您没有指定任何内容,则默认值为XmlAccessType.Property - 或者您的getter。我经历过Jaxb从类中获取xml元素,我错过了访问者类型注释,但仍然可以正常工作。
答案 3 :(得分:1)
只需查看本教程:jaxb的Mapping cyclic references to XML
我使用它并且运行良好:)
答案 4 :(得分:1)
我们也可以使用XStream库,我尝试了一个项目,其中JAXB给出了循环错误,但XStream成功处理了它