免责声明 #1:我对 XSD、数据库和 JPA 还很陌生——所以我的问题可能是荒谬的。
我有一个通过 XSD 指定的接口——我将接收 XML 文档并且需要将它们的内容保存到关系数据库中。我修改 XSD 的能力有限。接口本身由大量关系复杂的实体组成;有许多地方不希望在 XML 文档中要求完整的对象图。
本质上,我的 XSD 目前看起来像这样:
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:ns1="urn:foo"
targetNamespace="urn:foo" elementFormDefault="qualified" jxb:version="2.0"
jxb:extensionBindingPrefixes="hj orm">
<xsd:complexType name="Foo">
<xsd:sequence>
<xsd:element name="fooId" type="xsd:string" nillable="false">
<xsd:annotation>
<xsd:appinfo>
<hj:id />
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Bar">
<xsd:sequence>
<xsd:element name="BarId" type="xsd:string" nillable="false">
<xsd:annotation>
<xsd:appinfo>
<hj:id />
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="associatedFoo" type="xsd:string" nillable="false">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Baz">
<xsd:sequence>
<xsd:element name="BazId" type="xsd:string" nillable="false">
<xsd:annotation>
<xsd:appinfo>
<hj:id />
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="associatedFoos" type="xsd:string" nillable="false" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
我通过 hyperjaxb3 (0.5.6) 运行该 XSD 并获得一组用于 Foo、Bar 和 Baz 的 Java 类。我想要的是生成的数据库模式要求 Bar.associatedFoo 和 Baz.associatedFoos 都是实际的 fooId。但是,我不能只更新架构,以便例如 bar.associatedFoo 是 ns1:Foo 类型。所以,问题是:我该怎么做?
这里的推理是,XSD 中的每一种类型实际上都是大的、复杂的、相互关联的对象图。我不希望 Baz 的 XML 文档必须包含其每个 Foo 的完整 XML 表示。
(显然,一种选择是在创建 JPA 模式之后手动添加 DB 约束——但如果可能的话,我宁愿将此信息嵌入到 XSD 中。)
在更简单的情况下(Bar.associatedFoo),我可以使用 orm:column 注释直接修改列定义:
<hj:basic>
<orm:column column-definition="VARCHAR(255) REFERENCES myschema.Foo"/>
</hj:basic>
但是(a)我不确定如何将此尝试扩展到 Baz.associatedFoos 案例,并且(b)如果可能的话,我更喜欢不那么脆弱的东西(列定义字符串需要在 foo id 长度更改时进行调整,架构名称更改,或 Foo 的表名称更改;这取决于 JPA 决定在 CREATE TABLE foo 之前创建 TABLE Bar;并且直到运行时才产生错误)。
如果重要的话——我使用 openJPA 2.1.1 作为我的 JPA 实现,使用 Postgres 9.1 作为我的数据库。在 XSD 中,如果需要,我可以更改 ID 定义(使其成为 complexType、xsd:string 的命名别名或可能的其他一些更改),并添加我喜欢的任何 xsd:annotations,但我不能做很多我的类型的其他结构变化。
提前致谢!