java JAXB 映射对 XML 的循环引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3073364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:14:30  来源:igfitidea点击:

JAXB Mapping cyclic references to XML

javajpaxml-serializationjaxb

提问by Jordan Allan

I have an object graph that contains a cycle. How do I get JAXB to handle this? I tried using the @XmlTransientannotation in the child class but the JAXB marshaller still detects the cycle.

我有一个包含循环的对象图。我如何让 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;

...

}

采纳答案by bdoughan

The good thing about using JAXB is that it is a standard runtime with multiple implementations (just like JPA).

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

If you use EclipseLink JAXB (MOXy) then you have many extensions available to you for handling JPA entities including bi-directional relationships. This is done using the MOXy @XmlInverseReference annotation. It acts similar to @XmlTransient on the marshal and populates the target-to-source relationship on the unmarshal.

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

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

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; 

... 

} 

Other extensions are available including support for composite keys & embedded key classes.

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

To specify the EcliseLink MOXy JAXB implementation you need to include a jaxb.properties file in with your model classes (i.e. Contract) with the following entry:

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

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

回答by Stephen C

This pagein the "Unofficial JAXB Guide" offers three strategies for dealing with cycles. They are (in summary):

“非官方 JAXB 指南”中的这个页面提供了三种处理循环的策略。它们是(总而言之):

  • Mark one of the reference attributes that form the cycle as @XmlTransient.
  • Use @XmlID and @XmlIDREF so that the references are represented using XML ids arather than by containment.
  • Use the CycleRecoverable interface to deal with cycles programmatically.
  • 将形成循环的引用属性之一标记为@XmlTransient。
  • 使用 @XmlID 和 @XmlIDREF 以便使用 XML id 而不是包含来表示引用。
  • 使用 CycleRecoverable 接口以编程方式处理循环。

回答by Gunjan Kalra

XMLTransient almost always works for cycles. It might be a possibility that you have XMLTransient on the field level but you have not specified XMLAccessorType to be XmlAccessType.Field. If you don't specify anything the default is XmlAccessType.Property - or your getters. I have experienced Jaxb picking xml elements from getters from a class that I missed the accessor type annotations on and still work perfectly fine.

XMLTransient 几乎总是适用于循环。您可能在字段级别拥有 XMLTransient,但您尚未将 XMLAccessorType 指定为 XmlAccessType.Field。如果您未指定任何内容,则默认值为 XmlAccessType.Property - 或您的 getter。我经历过 Jaxb 从一个类的 getter 中挑选 xml 元素,我错过了访问器类型注释,但仍然可以正常工作。

回答by Up Vert

We can use XStreamlibrary as well, I tried it one project where JAXB was giving cyclic error but XStream handled it successfully

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

回答by LE GALL Beno?t

just look at this tutorial : Mapping cyclic references to XMLby jaxb

看看这个教程:通过 jaxb 将循环引用映射到 XML

I use it an it works well :)

我用它,效果很好:)