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
JPA: Implementing Model Hierarchy - @MappedSuperclass vs. @Inheritance
提问by huzeyfe
I am using Play Framework 1.2.4 with PostgreSQL
and JPA
. I would like to have a Model hierarchy and see that there are some alternatives to doing this.
我正在使用 Play Framework 1.2.4PostgreSQL
和JPA
。我想要一个模型层次结构,并看到有一些替代方法可以做到这一点。
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 @ManyToOne
relationships in my base class.
我有一个基类(它是抽象的)和两个扩展这个基类的具体类。我不想保留这个基类,而我想拥有具体的类。在基类中,我有另一个模型类作为属性,换句话说,我@ManyToOne
在基类中有关系。
My question is what is the best way of implementing this? Using @MappedSuperclass
or @Inheritance
with TABLE_PER_CLASS
strategy? 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, @MappedSupperclass
is different than the @Inheritance
annotation.
正如我在解释这个文章,@MappedSupperclass
是不是不同的@Inheritance
注解。
@MappedSuperclass
tells 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 @Inheritance
annotation is meant to materialize the OOP inheritance model in the database table structure. More, you can query a base class annotated with @Inheritance
but 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 @Inheritance
JPA annotation is to implement behavior-driven patterns like the Strategy Pattern.
现在,您想要使用@Inheritance
JPA 注释的原因是实现行为驱动的模式,如 Strategy Pattern。
On the other hand, @MappedSuperclass
is just a way to reuse both basic properties, associations, and even the entity @Id
using a common base class. Nevertheless, you can achieve almost the same goal using an @Embeddable
type. The only major difference is that you can't reuse an @Id
definition with @Embeddable
, but you can do it with @MappedSuperclass
.
另一方面,@MappedSuperclass
它只是一种@Id
使用公共基类重用基本属性、关联甚至实体的方法。尽管如此,您可以使用@Embeddable
类型实现几乎相同的目标。唯一的主要区别是您不能使用 重用@Id
定义@Embeddable
,但可以使用@MappedSuperclass
.