Java 抽象超类的 Hibernate (JPA) 继承映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4265454/
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
Hibernate (JPA) inheritance mapping of abstract super classes
提问by Tauren
My data model represents legal entities, such as a Business or a Person. Both are tax-paying entities, and both have a TaxID, a collection of phone numbers, and a collection of mailing addresses.
我的数据模型代表法律实体,例如企业或个人。两者都是纳税实体,都有一个税号、一组电话号码和一组邮寄地址。
I have a Java model with two concrete classes that extend an abstract class. The abstract class has properties and collections that are common to both concrete classes.
我有一个 Java 模型,其中包含两个扩展抽象类的具体类。抽象类具有两个具体类共有的属性和集合。
AbstractLegalEntity ConcreteBusinessEntity ConcretePersonEntity
------------------- ---------------------- --------------------
Set<Phone> phones String name String first
Set<Address> addresses BusinessType type String last
String taxId String middle
Address Phone
------- -----
AbsractLegalEntity owner AbstractLegalEntity owner
String street1 String number
String street2
String city
String state
String zip
I'm using HibernateJPA Annotationson a MySQLdatabase, with classes like this:
我在MySQL数据库上使用HibernateJPA Annotations,类如下:
@MappedSuperclass
public abstract class AbstractLegalEntity {
private Long id; // Getter annotated with @Id @Generated
private Set<Phone> phones = new HashSet<Phone>(); // @OneToMany
private Set<Address> address = new HashSet<Address>(); // @OneToMany
private String taxId;
}
@Entity
public class ConcretePersonEntity extends AbstractLegalEntity {
private String first;
private String last;
private String middle;
}
@Entity
public class Phone {
private AbstractLegalEntity owner; // Getter annotated @ManyToOne @JoinColumn
private Long id;
private String number;
}
The problem is that Phone
and Address
objects need to refer to their owner, which is an AbstractLegalEntity
. Hibernate complains:
问题是Phone
andAddress
对象需要引用它们的所有者,这是一个AbstractLegalEntity
. 休眠抱怨:
@OneToOne or @ManyToOne on Phone references an unknown
entity: AbstractLegalEntity
It seems like this would be a fairly common Java inheritance scenario, so I hope that Hibernate would support it. I've tried changing the mapping for AbstractLegalEntity based on a Hibernate forum question, no longer using @MappedSuperclass
:
看起来这将是一个相当常见的 Java 继承场景,所以我希望 Hibernate 支持它。我已经尝试根据Hibernate 论坛问题更改 AbstractLegalEntity 的映射,不再使用@MappedSuperclass
:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
However, now I get the following error. When reading up on this inheritance mapping type, it looks like I have to use SEQUENCE not IDENTITY, and MySQL doesn't support SEQUENCE.
但是,现在我收到以下错误。在阅读这种继承映射类型时,看起来我必须使用 SEQUENCE 而不是 IDENTITY,而且 MySQL 不支持 SEQUENCE。
Cannot use identity column key generation with <union-subclass>
mapping for: ConcreteBusinessEntity
I'm making more progress toward getting things working when I use the following mapping.
当我使用以下映射时,我在使事情正常工作方面取得了更多进展。
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="entitytype",
discriminatorType=DiscriminatorType.STRING
)
I'm thinking I should continue down this path. My concern is that I'm mapping it as an @Entity
when I really don't ever want an instance of AbstractLegalEntity to ever exist. I'd like to know if this is the right approach. What is the correct approach I should be taking for this situation?
我想我应该继续沿着这条路走下去。我担心的是,@Entity
当我真的不希望 AbstractLegalEntity 的实例存在时,我将其映射为一个。我想知道这是否是正确的方法。对于这种情况,我应该采取什么正确的方法?
采纳答案by milbr
Use:
用:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
AbstractLegalEntity
Then in database you will have one table for AbstractLegalEntity and tables for classes which extends AbstractLegalEntity class. You won't have instances of AbstractLegalEntity if it's abstract. Polymorphism can be here used.
然后在数据库中,您将有一个 AbstractLegalEntity 表和扩展 AbstractLegalEntity 类的类表。如果它是抽象的,您将没有 AbstractLegalEntity 的实例。这里可以使用多态。
When you use:
当您使用:
@MappedSuperclass
AbstractLegalEntity
@Entity
ConcretePersonEntity extends AbstractLegalEntity
It creates in database just one table ConcretePersonEntity but with columns from both classes.
它在数据库中只创建一个表 ConcretePersonEntity 但包含来自两个类的列。
回答by andbi
Add @Entity
annotation to AbstractLegalEntity
. Instance of AbstractLegalEntity
will never exist - hibernate will load appropriate extending instances - ConcreteBusinessEntity
or ConcretePersonEntity
according to Id field.
添加@Entity
注释到AbstractLegalEntity
. 实例AbstractLegalEntity
永远不会存在——休眠将加载适当的扩展实例——ConcreteBusinessEntity
或者ConcretePersonEntity
根据 Id 字段。
回答by Nicolas
You have to declare AbstracLegalEntity
as an @Entity
. Even with the @Entity
annotation, your class remains abstract. consequently, you will only have instance of concrete subclasses.
您必须声明AbstracLegalEntity
为@Entity
. 即使有@Entity
注释,您的类仍然是抽象的。因此,您将只有具体子类的实例。