Java JPA实体继承的正确数据库设计
我正在启动一个新项目,使用JPA2+Hibernate4.2.6进行数据访问 我的数据库中有两个表,代表两种不同类型的Java JPA实体继承的正确数据库设计,java,hibernate,inheritance,jpa,Java,Hibernate,Inheritance,Jpa,我正在启动一个新项目,使用JPA2+Hibernate4.2.6进行数据访问 我的数据库中有两个表,代表两种不同类型的应答,因此我有应答类型(a和应答类型(b表。 除一个字段外,其他字段都相同 现在我正在创建我的模型类,我想从一个普通的超类或接口Answer继承我的AnswerA和AnswerB实体 我读了一些关于实体继承的文档: 但我对如何构造我的DB和实体类来实现这一点没有明确的看法。您能帮我吗?您需要表答案-这对于特定的其他人来说是超级棒的,您应该在表中放置答案类型a和答案类型b的
应答
,因此我有应答类型(a
和应答类型(b
表。
除一个字段外,其他字段都相同
现在我正在创建我的模型类,我想从一个普通的超类或接口Answer
继承我的AnswerA
和AnswerB
实体
我读了一些关于实体继承的文档:
但我对如何构造我的DB和实体类来实现这一点没有明确的看法。您能帮我吗?您需要表
答案
-这对于特定的其他人来说是超级棒的,您应该在表中放置答案类型a
和答案类型b
的所有公共列。假设Answer.a\u id
是主键,然后Answer\u type\u a.a\u id
Answer\u type\u b.a\u id
同时是主键和外键
当然,不要忘记在answer\u type\u a
和answer\u type\u b
+---------+
| Answer |
+---------+ ----------------------->--+--------------+
| a_id +------) | answer_type_b|
---->-+--------------+ +--------------+
... | answer_type_a| | a_id |
+--------------+ ...
| a_id |
....
您需要使用公共字段创建一个名为
Answer
的类,并使用@MappedSuperclass
对其进行注释。此外,您将有两个实体类,分别名为AnswerA
和AnswerB
,它们将只保存“额外”字段
如果有两个表,那么需要使用TABLE\u PER\u类
继承类型。因此,将@heritation(strategy=heritancetype.TABLE\u PER\u CLASS)
添加到Answer
类中,并可能在AnswerA
和AnswerB
中添加@TABLE
注释
但如果我是你,我会使用一个表来显示所有答案,包括所有需要的列+一个鉴别器列,这样你就可以区分一行是答案类型a还是类型b。我知道你的问题是关于映射的: 您需要一个java类
Answer
,它实际上是您的超类。由于没有相应的DB表,因此必须用
现在这两个类出现了,它们是实体,因为它们被持久化在DB表中:
@Entity
@Table("answer_type_a")
public class AnswerA extends Answer {
//here you add the field that is not common with AnswerB
}
@Entity
@Table("answer_type_b")
public class AnswerB extends Answer {
//here you add the field that is not common with AnswerA
}
PS:IMHO您不需要任何继承注释,因为映射的超类不是实体。我最近也遇到过类似的情况。找到的最佳解决方案是使用抽象类作为超级类型,并将该类扩展到具体类型(表示实体) 因此,对于您的情况,您可以建立这样的模型
@MappedSuperClass
public abstract class Answer{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Integer id;
@Column
String commonFieldOne;
@Column
String commonFieldTwo;
@Column
String commonFieldThree;
...
}
注意,我使用了@MappedSuperClass
注释。这告诉JPA这是一个不会被实例化的超类,不应该有与之关联的数据库表。
还请注意,Id
将作为两个子表的主键,它是在此类中定义的
现在,对于具体的类(将映射到数据库中的表),可以使用@Entity
注释
@Entity
@Table("answer_type_a")
public class AnswerA extends Answer{
//All common fields from Answer table will be included in the DB tables as columns automatically
@Column
String uniqueFieldOne;
....
}
您可以对@Table(“answer\u type\u b”)
希望这有帮助 只需在数据库中创建一个表,例如包含两个字段的answer。必须有三个类:类1:答案,类2:答案类型A扩展答案,类3:答案类型B扩展答案。答案(超类)将有一个hbm文件,每个答案类型A和答案类型B将有两个hbm。在sybclass中,hbm文件包括:
<hibernate-mapping> <subclass name="com.test.Answer_Type_A"
extends="com.test.Answer">
<property name="fieldA" />
</subclass>
</hibernate-mapping>
您使用的是哪种版本的JPA和Hibernate?@PaulVargas更新了我的问题:为什么我更喜欢这种方法而不是创建@MappedSuperclass
类(避免在我的数据库中创建新表)?这在很大程度上取决于答案类型a
和答案类型b
中的信息量,假设有很大的区别,那么为了减少表开销,您需要单独的表。否则,使用MapperSuperclass或检查鉴别器()的可能性
<hibernate-mapping> <subclass name="com.test.Answer_Type_A"
extends="com.test.Answer">
<property name="fieldA" />
</subclass>
</hibernate-mapping>