【发布时间】:2016-07-18 09:21:48
【问题描述】:
短版适合仓促:
我的域模型中有各种表/实体具有相同的字段(UUID)。有一个表,我需要将此类实体的行/实例链接到其他 JPA 管理的实体。换句话说,该链接表中的字段实例不会预先知道。我能想到的两种方法是:
- 使用抽象实体和 TABLE_PER_CLASS 策略,或者
- 使用
@MappedSuperClass将实例的类名也存储在链接表中,或者类似的东西让我定义从正确的表中获取实际实例的逻辑。
两者在复杂性和性能方面各有优缺点。您认为哪个最好,是否有第三种选择,或者您过去曾尝试过类似的方法并建议/强烈警告不要这样做?
加长版如果您想要更多背景:
我有一个数据库/对象模型,其中许多类型都有一个公共字段:通用唯一标识符 (UUID)。原因是这些类型的实例可能会发生变化。更改遵循命令模型,并且它们的数据可以被封装并保持自身。让我们将这种变化称为“突变”。必须能够找出任何给定实体的数据库中存在哪些突变,反之亦然,存储的突变在哪个实体上运行。
为了存储“突变”,我们使用了一个名为MutationHolder 的表/实体。要将突变链接到其目标实体,可以使用MutationEntityLink。这些数据不直接在MutationHolder 上的唯一原因是因为可以有直接或间接链接,但这在这里并不重要,所以我把它省略了:
问题归结为如何在MutationEntityLink 中为entity 字段建模。我能想到两种方法。
首先是用UUID字段做一个抽象的@Entity注解类。 Customer、Contract 和 Address 将扩展它。所以这是一个 TABLE_PER_CLASS 策略。我假设我可以将其用作entity 字段的类型,尽管我不确定。但是,我担心这可能会导致严重的性能损失,因为 JPA 需要查询许多表才能找到实际实例。
第二种是简单地使用@MappedSuperClass,并将实体的UUID存储在MutationEntityLink的entity字段中。为了获得具有该 UUID 的实际实体,我必须以编程方式解决它。添加一个带有实体类名的附加列,或者允许我识别它或将它粘贴到 JPQL 查询中的其他内容。这需要更多的工作,但似乎更有效率。如果需要,我不反对编写一些实用程序类或做一些反射/自定义注释工作。
我的问题是这些方法中哪一种看起来最好?或者,您可能有更好的建议,或者注意到我遗漏了一些东西;例如,也许有一种方法可以添加类型列,即使具有 TABLE_PER_CLASS 继承以将 JPA 指向正确的表?也许您已经尝试过这样的事情并想警告我可能会出现的许多问题。
一些附加信息:
- 我们创建数据库架构,因此我们可以添加任何我们想要的内容。
- 单表继承策略不是一个选项。这些表必须保持不同。出于同样的原因,联合继承似乎也不合适。
- JPA 提供程序是 Hibernate,使用不属于 JPA 标准的东西不是问题。
【问题讨论】:
标签: java hibernate jpa inheritance orm