JPA:实现模型层次结构 - @MappedSuperclass与@Inheritance

2022-08-31 13:55:26

我正在使用Play Framework 1.2.4和。我希望有一个模型层次结构,并看到有一些替代方法可以做到这一点。PostgreSQLJPA

我有一个基类(它是抽象的)和两个具体类来扩展这个基类。我不想在想要具体类的同时保留这个基类。在基类中,我有另一个 Model 类作为属性,换句话说,我的基类中有关系。@ManyToOne

我的问题是实现这个目标的最佳方式是什么?使用还是与策略?我有点困惑,因为它们似乎几乎等同@MappedSuperclass@InheritanceTABLE_PER_CLASS

我对将来可能面临的查询和性能问题也有一些担忧。


答案 1

必须使用 MappedSuperClass 来继承属性、关联和方法。

当您有一个实体和多个子实体时,必须使用实体继承。

您可以通过回答以下问题来判断是否需要一个或另一个:模型中是否有其他实体可以与基类相关联?

如果是,则基类实际上是一个实体,您应该使用实体继承。如果不是,则基类实际上是一个类,其中包含多个不相关实体共有的属性和方法,您应该使用映射的超类。

例如:

  • 您可以有几种消息:SMS 消息、电子邮件或电话消息。一个人有一个消息列表。您还可以将提醒链接到邮件,而不管邮件的类型如何。在这种情况下,Message 显然是一个实体,必须使用实体继承。
  • 所有域对象都可以有创建日期、修改日期和 ID,因此您可以使它们从基本的 AbstractDomainObject 类继承。但是没有实体会与抽象域对象相关联。它将始终是与更具体的实体的关联:客户,公司,无论什么。在这种情况下,使用MappedSuperClass是有意义的。

答案 2

@MappedSupperclass与批注不同。@Inheritance

@MappedSuperclass告诉 JPA 提供程序包含基类持久性属性,就好像它们是由子类声明的,该子类扩展了用 注释的超类。@MappedSuperclass

但是,继承仅在 OOP 世界中可见,因为从数据库的角度来看,没有基类的指示。只有子类实体才具有关联的映射表。

该批注旨在具体化数据库表结构中的 OOP 继承模型。此外,您可以查询带批注的基类,但对于用 带批注的基类,则不能这样做。@Inheritance@Inheritance@MappedSuperclass

现在,您之所以要使用@Inheritance JPA 注释,是因为要实现行为驱动的模式,如策略模式。

另一方面,它只是一种使用公共基类重用基本属性,关联甚至实体的方法。但是,使用类型可以实现几乎相同的目标。唯一的主要区别是,您不能使用 重用 定义,但可以使用 @MappedSuperclass@MappedSuperclass@Id@Embeddable@Id@Embeddable


推荐