Подтвердить что ты не робот

JAXB Отображение циклических ссылок на XML

У меня есть граф объектов, содержащий цикл. Как мне заставить 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;

...

}
4b9b3361

Ответ 1

Хорошо, что использование 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

Ответ 2

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

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

Ответ 3

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

Ответ 5

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