JAXB Отображение циклических ссылок на XML - PullRequest
18 голосов
/ 19 июня 2010

У меня есть граф объектов, который содержит цикл.Как мне заставить JAXB справиться с этим?Я попытался использовать аннотацию @XmlTransient в дочернем классе, но маршаллер JAXB все еще обнаруживает цикл.

Ответы [ 5 ]

17 голосов
/ 19 июня 2010

Эта страница в «Неофициальном руководстве JAXB» предлагает три стратегии для работы с циклами.Это (в итоге):

  • Отметьте один из ссылочных атрибутов, которые формируют цикл, как @ XmlTransient.
  • Используйте @XmlID и @XmlIDREF, чтобы ссылки были представлены с использованием XMLидентификаторы выше, чем по содержанию.
  • Используйте интерфейс CycleRecoverable для программной обработки циклов.
12 голосов
/ 05 июля 2010

Преимущество использования 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, вам необходимо включить файл jaxb.properties в классы вашей модели (т.е. контракт) со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
6 голосов
/ 01 ноября 2011

XMLTransient почти всегда работает для циклов.Возможно, у вас есть XMLTransient на уровне поля, но вы не указали XMLAccessorType как XmlAccessType.Field.Если вы ничего не указали, по умолчанию используется XmlAccessType.Property - или ваши получатели.Я сталкивался с тем, что Jaxb выбирал элементы XML из геттеров из класса, в котором я пропустил аннотации типов аксессоров, и все еще прекрасно работает.

1 голос
/ 19 марта 2015

Мы также можем использовать библиотеку XStream , я пробовал один проект, в котором JAXB выдавал циклическую ошибку, но XStream обрабатывал ее успешно

1 голос
/ 23 августа 2010

просто посмотрите на этот урок: Отображение циклических ссылок на XML с помощью jaxb

Я использую его, и он хорошо работает:)

...