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;
...
}
Ответы
Ответ 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 и продолжаю работать отлично.
Ответ 4
просто посмотрите на этот учебник: Отображение циклических ссылок на XML jaxb
Я использую его, он хорошо работает:)
Ответ 5
Мы можем использовать XStream библиотеку, я попробовал один проект, где JAXB выдавал циклическую ошибку, но XStream успешно справился с ней