3

我正在处理的一个 java 应用程序具有类似于下面的关系的对象。在实际应用程序中,这两个对象都是 JPA 实体。


class Underlying{}

class Thing
{
  private Underlying underlying;

  public Underlying getUnderlying()
  {
    return underlying;
  }

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

应用程序中需要创建表单的 xml:

<template>
     <underlying>
        <thing/>
        <thing/>
        <thing/>
     </underlying>
</template>

所以我们有这样一种情况,对象图以与在 xml 中的表达方式相反的方向表达事物和基础之间的关系。

我希望使用 JAXB 创建 xml,但理想情况下我不想创建一个新的对象层次结构来反映 xml 中的关联。有什么方法可以从当前形式的实体中创建所需形式的 xml(通过使用 xml 注释或其他方式)?我没有任何使用 JAXB 的经验,但从我所做的有限研究来看,似乎不可能以任何直接的方式扭转关联的方向。任何帮助/建议将不胜感激。建议的另一种选择是使用 XLST 将 xml 转换为正确的格式。我还没有对这个主题进行任何研究,但是当我有更多信息时,我会补充这个问题。

谢谢,

马特。

4

3 回答 3

2

诀窍是让 Underlying 的实例知道 Thing 的相关实例。以下是您可以利用的几种方法。

选项#1 - 使关系双向

最简单的做法是使关系成为双向的。然后,您可以利用EclipseLink JAXB (MOXy)中的 @XmlInverseReference 扩展。注意:我是 MOXy 技术负责人:

选项 #2 - 使用 XmlAdapter

您可以创建基础的改编版本。在构建适应的基础对象时,XmlAdapter 可以查询 Thing 的实例以填充 things 属性:

于 2011-01-10T14:05:19.840 回答
1

在您的情况下,JAXB 可能不是正确的方法。当您需要将对象模型往返于 XML 和返回时,JAXB 是最佳选择,并且您对 XML 或对象模型都有一定的自由度。在这种情况下,您似乎没有纬度。恕我直言,没有适合您的 JAXB。

考虑到您将在某处对它们进行排序,这也是一个重要的 XML 元素数量。将整个图表和排序副本保存在内存中可能是昂贵的一面?因此,您需要Thing从 JPA 数据存储中获取 s 排序Underlying(让数据库进行排序),并将其流式传输到 ajavax.xml.stream.XMLStreamWriter以供输出。

在输入端,使用javax.xml.stream.XMLStreamReader.

于 2011-01-10T13:20:48.550 回答
1

在遇到类似问题时,我遇到了另一种可能性:

  • 将父引用属性添加到您的 JAXB 注释类
  • 使用 @XmlTransient 注释属性
  • 实现方法public void afterUnmarshal(Unmarshaller u, Object parent)
  • 像这样在这个方法中实现设置父指针的逻辑:this.parent= (ParentType) parent;当然你可以在那个方法中添加更多的东西。

顾名思义,该方法在解组后由 JAXB 调用。

参考:(相当旧的)讨论 forums.java.netJAXB 指南

我不能使用@XmlInverseReference,因为我们使用的 JAXB 实现与 MOXy 不同。虽然我开始欣赏@XmlAdapter,但我发现这种方法更简单,因为它不需要额外的类。

虽然这与您的问题描述不完全匹配,但我仍然认为这可以帮助未来的读者。

于 2011-02-01T10:05:51.617 回答