Граф объектов Java -> xml, когда необходимо изменить направление ассоциации объектов - PullRequest
3 голосов
/ 10 января 2011

Java-приложение, над которым я работаю, имеет объекты со схожими отношениями, описанными ниже. В реальном приложении оба объекта являются объектами JPA.


class Underlying{}

class Thing
{
  private Underlying underlying;

  public Underlying getUnderlying()
  {
    return underlying;
  }

  public void setUnderlying(final Underlying underlying)
  {
    this.underlying = underlying;
  }
}

В приложении есть требование для создания xml формы: <pre> <template> <underlying> <thing/> <thing/> <thing/> </underlying> </template>

Таким образом, у нас есть ситуация, когда граф объектов выражает отношение между Thing и Underlying в направлении, противоположном тому, как оно выражается в XML.

Я ожидаю использовать JAXB для создания xml, но в идеале мне не нужно создавать новую иерархию объектов для отражения ассоциаций в xml. Есть ли способ создать xml формы, требуемой от сущностей в их текущей форме (посредством использования xml-аннотаций или чего-то еще)? У меня нет никакого опыта использования JAXB, но из ограниченного исследования, которое я сделал, кажется, невозможно изменить направление ассоциации каким-либо простым способом. Любая помощь / совет будет принята с благодарностью. Еще один предложенный вариант - использовать XLST для преобразования XML в правильный формат. Я еще не исследовал эту тему, но добавлю к этому вопросу, когда у меня будет больше информации.

Спасибо

Мт.

Ответы [ 3 ]

2 голосов
/ 10 января 2011

Хитрость заключается в том, чтобы экземпляр Underlying осознавал, что такое Thing.Ниже приведено несколько подходов, которые вы можете использовать.

Вариант № 1 - сделать отношения двунаправленными

Самое простое, что можно сделать, - сделать отношения двунаправленными.Тогда вы могли бы использовать расширение @XmlInverseReference в EclipseLink JAXB (MOXy) .Примечание: я ведущий специалист MOXy:

Вариант № 2 - использовать XmlAdapter

Вы можете создать адаптированную версию Underlying.При создании адаптированного базового объекта XmlAdapter может запрашивать экземпляры Thing для заполнения свойства вещи:

1 голос
/ 01 февраля 2011

Борясь с подобной проблемой, я только что натолкнулся на дополнительную возможность:

  • Добавьте родительское свойство ссылки к вашим аннотированным классам JAXB
  • Аннотируйте свойство с помощью @ XmlTransient
  • Реализация метода public void afterUnmarshal(Unmarshaller u, Object parent)
  • Реализуйте логику для установки родительского указателя в этом методе следующим образом: this.parent= (ParentType) parent; Конечно, вы можете добавить больше вещей в этот метод.

Метод вызывается JAXB после демаршаллинга, как следует из названия.

Ссылки: (довольно старый) обсуждение на forums.java.net , JAXB Guide

Я не могу использовать @XmlInverseReference, поскольку мы используем реализацию JAXB, отличную от MOXy. Хотя я оценил @XmlAdapter, я нахожу этот подход более простым, так как он не требует дополнительных классов.

Хотя это не полностью соответствует вашему описанию проблемы, я все же думаю, что это может помочь будущим читателям.

1 голос
/ 10 января 2011

JAXB может не подходить в вашем случае. JAXB лучше всего подходит в тех случаях, когда вам необходимо выполнить возврат к объектной модели в обратном направлении и обратно, и у вас есть некоторая широта либо с XML, либо с объектной моделью. В этом случае у вас, кажется, нет широты. Нет JAXB для вас, ИМХО.

Это тоже нетривиальное количество элементов XML, учитывая, что вы будете где-то их сортировать. Вероятно, на дорогой стороне иметь целый граф и отсортированная копия в памяти? Таким образом, вы захотите получить Thing s из хранилища данных JPA, упорядоченного по Underlying (пусть база данных выполнит сортировку), и направить его в javax.xml.stream.XMLStreamWriter для вывода.

На стороне ввода используйте javax.xml.stream.XMLStreamReader.

...