1

我正在从NetBeans IDE 11.3Hibernate ORM 5.4.31中的Derby 10.14.2.0数据库生成POJO

它不会在实体类relationship-mappingshbm.xml或实体类中生成任何东西,如many-to-one/one-to-one)。

我将Derby 示例项目用于mcve

我使用了 Derby 示例数据库中的两个表。

产品和采购订单

产品表在 PurchaseOrder 中引用。

表 可以在下图中看到PurchaseOrderFOREIGN_KEY_PRODUCT_ID.

在此处输入图像描述

休眠.cfg

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect</property>
        <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="hibernate.connection.url">jdbc:derby://localhost:1527/sample</property>
        <property name="hibernate.connection.username">app</property>
        <property name="hibernate.connection.password">app</property>
       
        <mapping resource="com/pojo/Product.hbm.xml"/>
        <mapping resource="com/pojo/PurchaseOrder.hbm.xml"/>
    </session-factory>
</hibernate-configuration>  

我也尝试定义休眠属性

<property name="hibernate.default_catalog">app</property>

<property name="hibernate.default_schema">app</property>  

但不,这无济于事。

休眠.reveng.xml

<hibernate-reverse-engineering>
  <schema-selection match-schema="APP"/>
  <table-filter match-name="PRODUCT"/>
  <table-filter match-name="PURCHASE_ORDER"/>
</hibernate-reverse-engineering>

PurchaseOrder.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.pojo.PurchaseOrder" table="PURCHASE_ORDER" schema="APP" optimistic-lock="version">
        <id name="orderNum" type="int">
            <column name="ORDER_NUM" />
            <generator class="assigned" />
        </id>
        <property name="customerId" type="int">
            <column name="CUSTOMER_ID" not-null="true" />
        </property>
        <property name="productId" type="int">
            <column name="PRODUCT_ID" not-null="true" />
        </property>
        <property name="quantity" type="java.lang.Short">
            <column name="QUANTITY" />
        </property>
        <property name="shippingCost" type="big_decimal">
            <column name="SHIPPING_COST" precision="12" />
        </property>
        <property name="salesDate" type="date">
            <column name="SALES_DATE" length="10" />
        </property>
        <property name="shippingDate" type="date">
            <column name="SHIPPING_DATE" length="10" />
        </property>
        <property name="freightCompany" type="string">
            <column name="FREIGHT_COMPANY" length="30" />
        </property>
    </class>
</hibernate-mapping>  

在上面的PurchaseOrder.hbm.xml文件中,relationship mapping应该生成但你可以看到它丢失了

为什么relationship mapping不为 Derby 的示例数据库生成?

使用 MySQL 它工作正常。

Hibernate 不正确支持 Derby 吗?
什么是解决方案?

4

1 回答 1

1

简短的回答

你已经接近解决它了。简短的回答是:只需将此行添加到您的hibernate.cfg.xml配置文件(添加空目录):

<property name="hibernate.default_catalog"/>

我的hibernate.cfg.xml样子是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
    <property name="hibernate.connection.url">jdbc:derby://localhost:1527/sample</property>
    <property name="hibernate.connection.username">app</property>
    <property name="hibernate.connection.password">app</property>
    <property name="hibernate.default_catalog"/>
  </session-factory>
</hibernate-configuration>

使用此配置,NetBeans Hibernate POJO 向导可以很好地生成关系映射。查看生成的PurchaseOrder.hbm.xml文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 13.06.2021 12:06:13 by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="pojo.PurchaseOrder" table="PURCHASE_ORDER" schema="APP" optimistic-lock="version">
        <id name="orderNum" type="int">
            <column name="ORDER_NUM" />
            <generator class="assigned" />
        </id>
        <many-to-one name="customer" class="pojo.Customer" fetch="select">
            <column name="CUSTOMER_ID" not-null="true" />
        </many-to-one>
        <many-to-one name="product" class="pojo.Product" fetch="select">
            <column name="PRODUCT_ID" not-null="true" />
        </many-to-one>
        <property name="quantity" type="java.lang.Short">
            <column name="QUANTITY" />
        </property>
        <property name="shippingCost" type="big_decimal">
            <column name="SHIPPING_COST" precision="12" />
        </property>
        <property name="salesDate" type="date">
            <column name="SALES_DATE" length="10" />
        </property>
        <property name="shippingDate" type="date">
            <column name="SHIPPING_DATE" length="10" />
        </property>
        <property name="freightCompany" type="string">
            <column name="FREIGHT_COMPANY" length="30" />
        </property>
    </class>
</hibernate-mapping>

长答案

只是为了澄清,NetBeans 11.3 POJO 向导使用以下版本的休眠:

NetBeans 向导使用这些库从数据库生成 POJO。基本工作流程是:

  1. 从数据库中获取所有表,它使用getTables 的方法DatabaseMetaData
  2. 创建所有表的完全限定名称的列表。完全限定名是表格中的表名[catalog].[schema].[table]。Derby 数据库为目录参数返回一个空字符串(不是 null 而是 empty )。Hibernate 很好地处理了它,但是我们可以看到不同的数据库在这里表现不同。正如您在此处看到的,甚至还有关于它的评论
  3. 在第 2 步之后,我们有一个包含所有表的 Map 集合,其中包含 APP.CUSTOMER、APP.PRODUCT 等键。到目前为止,一切都很好。
  4. Hibernate 使用getExportedKeys方法获取特定表的所有外键,例如 APP.CUSTOMER 。
  5. Hibernate 工具尝试在表单中再次形成表的完全限定名称,[catalog].[schema].[table]但这次不太好,它以表名.APP.CUSTOMER 结束(请参阅应用程序前的点)。见这里。限定方法检查catalog!=nullgetExportedKeys将其作为空字符串而不是 null 返回。
  6. Hibernate 工具尝试使用在步骤 3 中创建的 Map 从外键映射表,但失败(因为点)。

解决方法有效,因为我们对 Hibernate 说目录不是空的而是空的。看到这

结论

因此,Hibernate 不能与 derby 一起工作的原因是 derby JDBC 客户端在返回有关外键的信息时表现不同。它为目录参数返回一个空字符串,但 MySQL 显然返回 null。

hibernate orm 框架在解析有关表的信息时对这种情况进行了特殊处理,但在使用外键时缺少它。所以我想它可以被认为是 Hibernate tools 4.3.1 中的一个错误

于 2021-06-13T10:11:07.680 回答