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

时间:2012-03-12 13:14:43

标签: java hibernate jpa inheritance orm

我将Play Framework 1.2.4与PostgreSQLJPA一起使用。我希望有一个Model层次结构,并且看到有一些替代方法可以做到这一点。

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

我的问题是实现这个的最佳方法是什么?在@MappedSuperclass策略中使用@InheritanceTABLE_PER_CLASS?我有点困惑,因为他们似乎几乎相当。

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

2 个答案:

答案 0 :(得分:117)

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

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

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

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

例如:

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

答案 1 :(得分:12)

正如我在this article中所解释的那样,@MappedSupperclass@Inheritance注释不同。

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

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

@Inheritance注释旨在实现数据库表结构中的OOP继承模型。此外,您可以查询使用@Inheritance注释的基类,但不能对使用@MappedSuperclass注释的基类执行此操作。

现在,您要使用@Inheritance JPA annotation is to implement behavior-driven patterns like the Strategy Pattern

的原因

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