Hyperjaxb3错误的jpa关系

问题描述 投票:0回答:2

我的 xsd,如附加文件中所示,报告关系 ROOT 1-->1 标头,但是当我使用 hyperjaxb3 构建项目时,它创建了一个错误的 @ManyToOne 注释,而不是 @OneToOne,因为 xsd 有默认序列约束(1): 创建的代码是:

@ManyToOne(targetEntity = HeaderType.class, cascade = {
CascadeType.ALL
})
@joincolumn(name = "HEADER_ROOT_HJID")
public HeaderType getHeader() {

摘自 XSD:

enter image description here

摘录自 XSD 的文字(针对 rick)

<xs:element name="ROOT">
    <xs:complexType>
        <xs:sequence maxOccurs="1">
            <xs:element name="Header" type="tns:HeaderType" maxOccurs="1"/>
            <xs:element name="Data_Block" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="Sensing_Start_Time" type="xs:string"/>
                        <xs:element name="Sensing_Stop_Time" type="xs:string"/>
                        <xs:element name="List_of_Acquisitions" maxOccurs="1">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="Acquisition" type="tns:AcquisitionType" maxOccurs="unbounded"/>
                                </xs:sequence>
                                <xs:attribute name="count" type="xs:int" use="required"/>
                            </xs:complexType>
                        </xs:element>
                        <xs:element name="List_Of_Dumps" minOccurs="0" maxOccurs="1">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="Dump" type="tns:DumpType" maxOccurs="unbounded"/>
                                </xs:sequence>
                                <xs:attribute name="count" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="type" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
xsd jaxb hyperjaxb
2个回答
0
投票
当源实体引用单个目标实体时,

HiSrc HyperJAXB Maven Plugin 会生成

@ManyToOne
JPA 注释。这是预期的行为。在没有其他信息的情况下,这种选择提供了外国参考,但不推断所有权。当所有权is存在时,目标实体的生命周期就绑定到源,这是一个更强的选择。

当然,您的设计可以在适当的时候选择将所有权应用于这种类型的关系。要生成

@OneToOne
关系,您可以定义此 JAXB 绑定:

RootHeader.xjb

...
<jaxb:bindings node="xs:element[@name='Root']//xs:element[@name='header']">
    <hj:one-to-one>
        <!-- Optional, custom column name.
        <orm:join-column name="HEADER_ROOT_HJID"/>
        -->
    </hj:one-to-one>
</jaxb:bindings>
...

使用来自 HyperJAXB 命名空间的自定义将上述绑定应用于目标

header
元素。或者,您可以使用
orm
命名空间来自定义 JPA 用于将源实体
Root
连接到目标实体
Header
的数据库列;否则,HyperJAXB 将选择适当的列名称来表示连接。

JAXB 绑定文件 RootHeader.xjb 应用于 XML 模式文件 RootHeader.xsd 以生成 JAXB/JPA 实体。这些类生成为

target/generated-sources/xjc/org/example/root_header/
并包含在类路径中。

执行

下载此 demo (zip) 并将其解压到本地文件夹后,您可以使用两个 JPA 提供程序之一运行测试和/或应用程序:

注意: 该演示是一个独立的 Maven 项目。

Eclipselink

mvn -Peclipselink clean test
mvn -Peclipselink clean compile exec:java

休眠

mvn -Phibernate clean test
mvn -Phibernate clean compile exec:java

输出显示使用Hibernate的测试结果。

持久化:H2或PostgreSQL

默认情况下,该项目使用本地 H2 数据库。当应用程序创建其

EntityManagerFactory
时,H2 数据库会自动创建。

或者,可以重新配置该项目以使用您自己的 PostgreSQL 数据库服务器。

方法

hisrc-hyperjaxb-maven-plugin 配置为使用提供的 RootHeader.xsd 模式生成 JPA/JAXB 类。该模式提供了命名空间

"http://org.example/root_header"
JAXB 使用它来使用自己的命名约定创建 Java
package
名称。

作为默认选项,使用这些

XJC
hisrc-basicjaxb-plugins 生成 Java 内置 Object 方法的更高级实现。特别是,示例项目使用
toString
插件来显示未编组的 Root 对象的
人类可读
表示。

注意: hisrc-hyperjaxb-maven-plugin 扩展了 hisrc-higherjaxb-maven-plugin预配置 几个 XJC hisrc-basicjaxb-plugins;因此,运行时类路径需要 hisrc-basicjaxb-runtime 依赖项。有关配置详细信息的更多帮助,请参阅...

mvn hisrc-hyperjaxb:help -Ddetail=true
测试

JUnit 测试类 RoundtripTest.java 扫描示例文件并调用方法

super.checkSample(File samle)
将每个文件提供给测试人员。对于此项目,创建了
EntityManagerFactory
JAXBContext
,并且 samples 路径中的每个文件为:

  • 解组到初始
    Root
    对象
  • 解组到标准具
    Root
    对象
  • JPA 事务已启动。
    • 初始对象被合并到持久化会话中
  • JPA 事务已提交
  • 创建了一个新的 JPA
    EntityManager
    em,实例
    • 新的em用于通过id
      加载持久化的
      Root
    • 比较标准具、合并和加载的
      Root
      对象是否相等
  • em 已关闭,每个
    Root
    对象都被编组以供在日志中查看

成功后,每个对象都会被编组用于日志记录和您的审查

示范

具有

main(...)
方法的 Java 标准引擎应用程序位于
org.example.root_header.Main
。该应用程序使用以下命令执行:

mvn -Peclipselink clean compile exec:java -Dexec.args="src/test/samples/root-header-01.xml"
OR
mvn -Phibernate   clean compile exec:java -Dexec.args="src/test/samples/root-header-01.xml"

免责声明:我是HiSrc项目的维护者。


0
投票

作为 Rick 答案的补充,您可以从高源原始文档中找到以下内容(将在 jaxb-tools 的 github wiki 中反向移植)

https://web.archive.org/web/20150929032052/http://confluence.highsource.org/display/HJ3/Reference+-+single+page

一对一映射

您可以使用

hj:one-to-one
自定义元素将复杂的单一属性映射为
@OneToOne
而不是
@ManyToOne
:

来自此处的示例(请参阅前缀的标头声明)

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"

    xmlns:hj="urn:hyperjaxb3.jvnet.org:ejb:schemas:customizations"
    xmlns:orm="https://jakarta.ee/xml/ns/persistence/orm"

<xs:element name="one-to-one-join-column" type="test:three" minOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <hj:one-to-one>
                <orm:join-column name="O2OJC_THREE_ID"/>
            </hj:one-to-one>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

这将在 JPA 实体之间生成预期的

@OneToOne
关系,代码如下:

@XmlElement(name = "one-to-one-join-column")
protected Three oneToOneJoinColumn;
 
@OneToOne(targetEntity = Three.class, cascade = {
    CascadeType.ALL
})
@JoinColumn(name = "O2OJC_THREE_ID")
public Three getOneToOneJoinColumn() {
    return oneToOneJoinColumn;
}
 
public void setOneToOneJoinColumn(Three value) {
    this.oneToOneJoinColumn = value;
}
© www.soinside.com 2019 - 2024. All rights reserved.