NetBeans > Hibernate Wizards > Create POJOs from database" (Derby) 在 hbm.xml 中不生成任何关系映射
NetBeans > Hibernate Wizards > Create POJOs from database" (Derby) does not generate any relationship-mappings in hbm.xml
我正在从 Derby 10.14.2.0 数据库中生成 POJO NetBeans IDE 11.3, 休眠 ORM 5.4.31.
它不会在 hbm.xml
或像 many-to-one/one-to-one
这样的实体 类 中生成任何 relationship-mappings
。
我将 Derby 示例项目 用于 mcve。
我使用了 Derby 示例数据库中的两个 table。
产品和采购订单
采购订单中引用了产品 table。
Table PurchaseOrder
有 FOREIGN_KEY_PRODUCT_ID.
可以在下图中看到。
hibernate.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>
但是不行,这没用。
hibernate.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 吗?
什么是解决方案?
简答
您快要解决它了。简短的回答是:只需将此行添加到您的 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 向导使用以下休眠版本:
- 休眠 ORM 4.3.1.Final
- 休眠工具 4.3.1.Final
NetBeans 向导使用这些库从数据库生成 POJO。基本工作流程是:
- 从数据库中获取所有table,它使用方法getTables
共
DatabaseMetaData
- 创建所有 table 的完全限定名称的列表。完全限定名称是
[catalog].[schema].[table]
形式的 table 的名称。 Derby 数据库 returns catalog 参数的空字符串(不是 null 而是空的)。 Hibernate 很好地处理了它,但我们可以看到不同的数据库在这里表现不同。正如您在这里看到的,甚至还有 comment。
- 在第 2 步之后,我们有一个包含所有 table 的 Map 集合,这些集合具有 APP.CUSTOMER、APP.PRODUCT 等键。到目前为止,还不错。
- Hibernate 使用 getExportedKeys 方法获取特定 table 的所有外键,例如 APP.CUSTOMER。
- Hibernate 工具再次尝试以
[catalog].[schema].[table]
的形式形成 table 的完全限定名称,但这次不太好,它以 table 名称结尾 .APP.CUSTOMER(见应用前的点)。参见 here。 qualify 方法检查 catalog!=null
但 getExportedKeys
returns 它是空字符串而不是 null。
- Hibernate 工具尝试使用在第 3 步创建的映射从外键映射 table,但失败了(因为点)。
解决方法有效,因为我们告诉 Hibernate 目录不是空的而是空的。看到这个 lines.
结论
所以 Hibernate 不能与 derby 一起工作的原因是因为 derby JDBC 客户端在返回有关外键的信息时表现不同。它 returns 目录参数的空字符串但 MySQL 显然 returns null.
hibernate orm 框架在解析有关 tables 的信息时对这种情况有特殊处理,但在处理外键时却没有。所以我想它可以被认为是 Hibernate 工具 4.3.1
中的一个错误
我正在从 Derby 10.14.2.0 数据库中生成 POJO NetBeans IDE 11.3, 休眠 ORM 5.4.31.
它不会在 hbm.xml
或像 many-to-one/one-to-one
这样的实体 类 中生成任何 relationship-mappings
。
我将 Derby 示例项目 用于 mcve。
我使用了 Derby 示例数据库中的两个 table。
产品和采购订单
采购订单中引用了产品 table。
Table PurchaseOrder
有 FOREIGN_KEY_PRODUCT_ID.
可以在下图中看到。
hibernate.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>
但是不行,这没用。
hibernate.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 吗?
什么是解决方案?
简答
您快要解决它了。简短的回答是:只需将此行添加到您的 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 向导使用以下休眠版本:
- 休眠 ORM 4.3.1.Final
- 休眠工具 4.3.1.Final
NetBeans 向导使用这些库从数据库生成 POJO。基本工作流程是:
- 从数据库中获取所有table,它使用方法getTables
共
DatabaseMetaData
- 创建所有 table 的完全限定名称的列表。完全限定名称是
[catalog].[schema].[table]
形式的 table 的名称。 Derby 数据库 returns catalog 参数的空字符串(不是 null 而是空的)。 Hibernate 很好地处理了它,但我们可以看到不同的数据库在这里表现不同。正如您在这里看到的,甚至还有 comment。 - 在第 2 步之后,我们有一个包含所有 table 的 Map 集合,这些集合具有 APP.CUSTOMER、APP.PRODUCT 等键。到目前为止,还不错。
- Hibernate 使用 getExportedKeys 方法获取特定 table 的所有外键,例如 APP.CUSTOMER。
- Hibernate 工具再次尝试以
[catalog].[schema].[table]
的形式形成 table 的完全限定名称,但这次不太好,它以 table 名称结尾 .APP.CUSTOMER(见应用前的点)。参见 here。 qualify 方法检查catalog!=null
但getExportedKeys
returns 它是空字符串而不是 null。 - Hibernate 工具尝试使用在第 3 步创建的映射从外键映射 table,但失败了(因为点)。
解决方法有效,因为我们告诉 Hibernate 目录不是空的而是空的。看到这个 lines.
结论
所以 Hibernate 不能与 derby 一起工作的原因是因为 derby JDBC 客户端在返回有关外键的信息时表现不同。它 returns 目录参数的空字符串但 MySQL 显然 returns null.
hibernate orm 框架在解析有关 tables 的信息时对这种情况有特殊处理,但在处理外键时却没有。所以我想它可以被认为是 Hibernate 工具 4.3.1
中的一个错误