2010-06-18 104 views
18

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

@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; 

... 

} 

回答

12

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

如果您使用EclipseLink JAXB(MOXy),则可以使用许多扩展来处理包括双向关系的JPA实体。这是使用MOXy @XmlInverseReference注释完成的。它的作用类似于编组上的@XmlTransient,并在解组上处理目标到源的关系。

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; 

... 

} 

其他扩展可用,包括用于复合键&嵌入式重点班的支持。

要指定需要包括jaxb.properties文件与您的模型类(即合同)具有以下条目EcliseLink莫西JAXB实现:通过JAXB Mapping cyclic references to XML

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

也许这是一个JAX-RS问题。我仍然得到异常说周期被检测到 - javax.ws.rs.WebApplicationException:javax.xml.bind.MarshalException - 与链接的异常: [com.sun.istack.SAXException2:在对象图中检测到一个循环。 – 2010-07-06 21:49:15

+0

您将需要添加指定EclipseLink MOXy运行时的jaxb.properties文件。我已将说明添加到上面的答案中。 – 2010-07-07 14:24:49

+0

工程很棒。谢谢。 – 2010-07-07 18:26:49

17

This page“非官方JAXB指南”中提供了三种策略应对周期。它们是(总结):

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

XmlID和XmlIDREF易于使用。将XmlID注释添加到方法public String getId(){return Integer.toString(System.identityHashCode(this)); }并且您可以使用简单的方法为您的XML元素分配唯一的ID。 – astraujums 2017-11-07 00:50:35

1

单看本教程

我用它的效果很好:)

6

XMLTransient几乎总是适用于周期。您可能在字段级别上有XMLTransient,但您尚未指定XMLAccessorType为XmlAccessType.Field。如果您不指定任何内容,则默认值为XmlAccessType.Property - 或您的获取者。我曾经遇到过Jaxb从类中的getter中挑选xml元素,我错过了访问器类型注释并仍然工作得很好。

1

我们可以用XStream库为好,我试了一个项目中,JAXB是给循环错误,但是XStream的成功处理它

+1

习惯上显示如何使用它除了提供参考。请[编辑]你的答案包括这个。 – 2015-03-22 11:19:16