JAXB 映射对 XML 的循环引用

2022-09-02 12:12:23

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

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

...

}

答案 1

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

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

答案 2

使用 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; 

... 

} 

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

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

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

推荐