在JPA中链接不同实体类型的最佳方法

G_H*_*G_H 10 java orm inheritance hibernate jpa

草率的简短版本:

我的域模型中有各种表/实体,它们具有相同的字段(UUID).有一个表我需要将这些实体的行/实例链接到其他JPA管理的实体.换句话说,该链接表中的字段实例将不会被预先知道.我能想到的两种方法是:

  • 使用抽象实体和TABLE_PER_CLASS策略,或
  • 使用@MappedSuperClass商店中的链接表中的实例的类的名称为好,或者类似的东西,让我定义逻辑右表中得到实际的实例.

两者在复杂性和性能方面都有优点和缺点.您认为最好的是哪种,是否有第三种选择,或者您曾经尝试过类似的东西,并建议/强烈警告?

长版本,以防您想要更多背景:

我有一个数据库/对象模型,其中许多类型有一个共同的字段:通用唯一标识符(UUID).原因是这些类型的实例可能会发生变化.这些更改遵循命令模型,并且可以封装其数据并保持其自身.让我们把这种变化称为"变异".必须有可能找出数据库中存在哪些突变对于任何给定实体,反之亦然,存储突变在哪个实体上运行.

将以下具有UUID的实体作为(极其简化)示例: 可变实体

为了存储"突变",我们使用一个名为的表/实体MutationHolder.要将突变链接到其目标实体,有一个MutationEntityLink.这个数据没有直接MutationHolder关联的唯一原因是因为可以有直接或间接的链接,但这里的重要性不大,所以我把它排除在外: 突变实体

问题归结为我如何为该entity领域建模MutationEntityLink.我能想到两种方法.

第一个是@Entity使用UUID字段创建一个带抽象注释的类.Customer,Contract并且Address将扩展它.所以这是一个TABLE_PER_CLASS策略.我假设我可以使用它作为entity场的类型,虽然我不确定.但是,我担心这可能会导致严重的性能损失,因为JPA需要查询许多表来查找实际的实例.

二是简单地使用@MappedSuperClass,只是存储UUID在实体entity领域MutationEntityLink.为了获得具有该UUID的实际实体,我必须以编程方式解决它.添加一个包含实体类名的附加列,或者允许我识别它或将其粘贴到JPQL查询中的其他内容.这需要更多的工作,但似乎更有效.如果需要,我不反对编写一些实用程序类或进行一些反射/自定义注释工作.

我的问题是哪种方法看起来最好?或者,您可能有更好的建议,或者注意到我遗漏了一些东西; 例如,也许有一种方法来添加一个类型列,即使使用TABLE_PER_CLASS继承将JPA指向右表?也许你已经尝试过这样的事情并且想要警告我可能出现的许多问题.

一些额外的信息:

  • 我们创建数据库模式,因此我们可以添加任何我们想要的东西.
  • 单表继承策略不是一种选择.表必须保持不同.出于同样的原因,联合继承似乎也不合适.
  • JPA提供程序是Hibernate,使用不属于JPA标准的东西不是问题.

Tho*_*mas 7

如果实体除了拥有uuid之外没有任何共同点,我会使用您描述的第二种方法:使用MappedSuperclass.使公共超类成为实体会阻止您在需要时使用不同的继承策略,即使没有实例存在也需要该超级实体的表,并且从业务角度来看它是错误的.

链接本身可以以多种方式实现,例如,您可以MutationEntityLink为每个实体创建子类以进行映射(例如CustomerMutationEntityLink等)或按照您的描述进行操作,即仅存储uuid以及一些鉴别器/类型信息并以编程方式解析(我们'重新使用这种方法来获得类似的东西.)