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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9667703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:53:47  来源:igfitidea点击:

JPA: Implementing Model Hierarchy - @MappedSuperclass vs. @Inheritance

javahibernatejpainheritanceorm

提问by huzeyfe

I am using Play Framework 1.2.4 with PostgreSQLand JPA. I would like to have a Model hierarchy and see that there are some alternatives to doing this.

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

I have a base class (which is abstract) and two concrete classes extending this base class. I don't want to persist this base class while I want to have concrete classes. In the base class, I have another Model classes as properties, in other words, I have @ManyToOnerelationships in my base class.

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

My question is what is the best way of implementing this? Using @MappedSuperclassor @Inheritancewith TABLE_PER_CLASSstrategy? I am a bit confused as they seem virtuallyequivalent.

我的问题是实现这一点的最佳方法是什么?使用@MappedSuperclass还是@Inheritance使用TABLE_PER_CLASS策略?我有点困惑,因为它们看起来几乎相同。

I also have some concerns about querying and performance issues that I might face in future.

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

采纳答案by JB Nizet

MappedSuperClass must be used to inherit properties, associations, and methods.

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

Entity inheritance must be used when you have an entity, and several sub-entities.

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

You can tell if you need one or the other by answering this questions: is there some other entity in the model which could have an association with the base class?

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

If yes, then the base class is in fact an entity, and you should use entity inheritance. If no, then the base class is in fact a class that contains attributes and methods that are common to several unrelated entities, and you should use a mapped superclass.

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

For example:

例如:

  • You can have several kinds of messages: SMS messages, email messages, or phone messages. And a person has a list of messages. You can also have a reminder linked to a message, regardless of the kind of message. In this case, Message is clearly an entity, and entity inheritance must be used.
  • All your domain objects could have a creation date, modification date and ID, and you could thus make them inherit from a base AbstractDomainObject class. But no entity will ever have an association to an AbstractDomainObject. It will always be an association to a more specific entity: Customer, Company, whatever. In this case, it makes sense to use a MappedSuperClass.
  • 您可以拥有多种消息:SMS 消息、电子邮件消息或电话消息。一个人有一个消息列表。无论消息类型如何,您还可以将提醒链接到消息。在这种情况下,Message 显然是一个实体,必须使用实体继承。
  • 您所有的域对象都可以具有创建日期、修改日期和 ID,因此您可以使它们从基础 AbstractDomainObject 类继承。但是任何实体都不会与 AbstractDomainObject 有关联。它始终是与更具体实体的关联:客户、公司等。在这种情况下,使用 MappedSuperClass 是有意义的。

回答by Vlad Mihalcea

As I explained in this article, @MappedSupperclassis different than the @Inheritanceannotation.

正如我在解释这个文章@MappedSupperclass是不是不同的@Inheritance注解。

@MappedSuperclasstells the JPA provider to include the base class persistent properties as if they were declared by the child class extending the superclass annotated with @MappedSuperclass.

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

However, the inheritance is only visible in the OOP world, since, from a database perspective, there's no indication of the base class. Only the child class entity will have an associated mapped table.

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

The @Inheritanceannotation is meant to materialize the OOP inheritance model in the database table structure. More, you can query a base class annotated with @Inheritancebut you can't do that for a base class annotated with @MappedSuperclass.

@Inheritance注释是为了兑现在数据库表结构的OOP继承模型。此外,您可以查询用 注释的基类,@Inheritance但不能查询用 注释的基类@MappedSuperclass

Now, the reason why you'd want to use the @InheritanceJPA annotation is to implement behavior-driven patterns like the Strategy Pattern.

现在,您想要使用@InheritanceJPA 注释的原因是实现行为驱动的模式,如 Strategy Pattern

On the other hand, @MappedSuperclassis just a way to reuse both basic properties, associations, and even the entity @Idusing a common base class. Nevertheless, you can achieve almost the same goal using an @Embeddabletype. The only major difference is that you can't reuse an @Iddefinition with @Embeddable, but you can do it with @MappedSuperclass.

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