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

我使用的是带有 PostgreSQLJPA的 Play Framework 1.2.4。我希望有一个模型层次结构,并看到有一些替代方案来做到这一点。

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

我的问题是,实现这一目标的最佳方式是什么?使用 @MappedSuperclass@InheritanceTABLE_PER_CLASS策略?我有点困惑,因为他们似乎相当于 实际上

我还担心将来可能会遇到的查询和性能问题。

39697 次浏览

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

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

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

如果是,则基类实际上是一个实体,您应该使用实体继承。如果没有,那么基类实际上是一个包含属性和方法的类,这些属性和方法对于几个不相关的实体是通用的,您应该使用一个映射的超类。

例如:

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

@MappedSupperclass@Inheritance注释不同。

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

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

@Inheritance注释意味着在数据库表结构中实现 OOP 继承模型。此外,可以查询用 @Inheritance注释的基类,但不能查询用 @MappedSuperclass注释的基类。

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

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