使用单表的休眠继承
Posted
技术标签:
【中文标题】使用单表的休眠继承【英文标题】:Hibernate inheritance using single table 【发布时间】:2011-11-19 14:29:24 【问题描述】:在我们的系统中,我们存储订单。我们的项目中总是有客户特定的代码,但我们会尽可能地标准化。现在我正在使用 Hibernate 进行测试,看看我们是否可以使用它来改进我们的数据访问对象。我在理解 Hibernate 继承的可能性时遇到了一些问题。让我概述一下这个问题:
我们有 4 层软件:
-
核心库
客户特定库(核心扩展)
应用程序(使用核心库和客户特定库的应用程序)
数据库
核心库
在核心库中,我们有以下关于订单的模型
-
IOorder(接口)
顺序(类、核心顺序实现、默认实现)
假设订单具有以下默认字段:
身份证 CUSTOMER_NAME 订单日期 交货日期客户特定库
在客户特定的库中,我们有以下关于订单的内容:
-
CustomerOrder(类,订单扩展)。
现在订购我们系统的客户除了上述字段外,还希望存储国家和优先级。客户特定字段为:
国家 优先级应用
应用程序通过工厂加载正确的 Order 类(Order 或 CustomerOrder)。工厂以某种方式知道是否有客户特定的实施。
数据库
在 de 数据库中,我们希望有 1 个表(出于性能原因),我们的核心/默认表(因此没有任何客户特定的扩展)如下所示:
create table ORDER
(
OR_ID VARCHAR2(10) not null constraint OR_ID_PK primary key,
OR_CUSTOMER_NAME VARCHAR2(20),
OR_ORDER_DATE datetime,
OR_DELIVERY_DATE datetime
);
对于需要额外两个字段的客户,我们将创建相同的表:
create table ORDER
(
OR_ID VARCHAR2(10) not null constraint OR_ID_PK primary key,
OR_CUSTOMER_NAME VARCHAR2(20),
OR_ORDER_DATE datetime,
OR_DELIVERY_DATE datetime,
OR_COUNTRY VARCHAR2(20),
OR_PRIORITY NUMBER
);
Java/休眠
现在我的问题是如何使用 Hibernate 仅使用 1 个表在 Java 中对此进行建模。核心 Order 实体不知道 CustomerOrder 中可用的任何额外列。我结合继承研究了 Hibernate 的一些选项,例如使用策略 InheritanceType.SINGLE_TABLE。但我相信这需要一个鉴别器列,而我没有。
Hibernate 有哪些选择?
【问题讨论】:
嗨长袍。您是直接使用 Hibernate,还是通过 JPA? 【参考方案1】:我不知道我是否正确,但您似乎有两个继承 Order 的类 Order 和 CustomerOrder。如果这是真的,那么单表策略在没有任何配置的情况下非常适合,并且鉴别器列是类名,所以如果记录属于 Order 你将得到 Order in 作为鉴别器值,如果是 CustomerOrder 你将得到 CustomerOrder 作为鉴别器值。这是休眠的默认行为,您可以对其进行修改。
【讨论】:
接受了这个,因为它更关注我的问题,这似乎是对如何使用鉴别器的误解。【参考方案2】:在这种情况下,您永远不会同时拥有两种实体(Order 和 CustomerOrder)。如果没有自定义,则只有 Orders,如果有自定义,则只有 CustomerOrders。
实际上,您可以假设您始终只有 CustomerOrder,但该类并不完全在您的控制之下,可以由客户提供的另一个类替换。
所以我可能会将 Order 设为 MappedSuperclass(即不构成实体但具有由实体继承的持久字段的类)。
在可由客户自定义的扩展 jar 中,我将定义 CustomerOrder 实体,该实体将仅扩展 Order 而不会添加任何其他字段。这个 CustomerOrder 类将以源代码的形式提供给客户,客户可以用他们自己的实现来替换它,并带有额外的字段。
【讨论】:
谢谢,我尝试了 MappedSuperclass on Order。但是,我不确定这在我的设置中是否有用。因为我还需要在核心库中有一个订单实体。使用 MappedSuperclass 我不会有一个核心实体(除非我当然做一个)。我认为我的主要问题是鉴别器。现在我更好地理解了它的用途。所以我在我的数据库表中添加了一个鉴别器列来让它工作。以上是关于使用单表的休眠继承的主要内容,如果未能解决你的问题,请参考以下文章