Java Hibernate和JPA的好继承策略是什么?

Java Hibernate和JPA的好继承策略是什么?,java,hibernate,inheritance,jpa,annotations,Java,Hibernate,Inheritance,Jpa,Annotations,我有这样的情况: 我有一个实体,Person,它包含一个人的所有个人详细信息,如出生日期、街道地址、市政ecc。 我有一个实体ClubMember,它描述一个俱乐部的成员,并包含一些字段,如:注册日期、成员类型、信用、ecc ecc 因此,ClubMember是一个人,我认为用继承来描述这一点是正确的: ClubMember扩展Person,但是,什么类型的策略 我将在数据库中获得两个表,Person和ClubMember,其中ClubMember包含id\u Person,类似于@OneToO

我有这样的情况:

我有一个实体,
Person
,它包含一个人的所有个人详细信息,如出生日期、街道地址、市政ecc。 我有一个实体
ClubMember
,它描述一个俱乐部的成员,并包含一些字段,如:注册日期、成员类型、信用、ecc ecc

因此,
ClubMember
是一个
,我认为用继承来描述这一点是正确的:
ClubMember扩展Person
,但是,什么类型的策略

我将在数据库中获得两个表,
Person
ClubMember
,其中
ClubMember
包含
id\u Person
,类似于
@OneToOne
关系,但保留实体之间的继承;这是可能的(并且是正确的)

JOINED
是最接近我目标的策略,但我失去了table
ClubMember
ID
字段,事实上
ID
成为table
Person
ID

编辑:下面的答案假设为NHibernate,如果它不适用于Hibernate,请事先道歉

这并不总是琐碎的,即使它可以被琐碎地实现(见下文),并且应该被彻底考虑。根据我的经验,最好坚持使用好的旧聚合,甚至只是字段,其中每个ClubMember都有一个人,而不是一个人。这可能感觉不完全正确,但在配置、CRUD操作和抽象DAO类中更容易使用。自动映射工具通常不支持开箱即用的子类化

此外,与您的数据库和DAL一起工作的人员将理解此映射(即,Person作为到ClubMember的一对一映射,将非null添加到
Person
-属性,并且您也有您的约束),因为它更像数据库。当然,您可能会争辩说ORM的整个思想就是消除这种相似性;)


如果您想在这条道路上进行试验,或者如果您想看看它是如何完成的,并将其应用于您的情况。这有点基本,但你会明白的。如果您使用Fluent NHibernate,它会变得更容易,请参见。

我会让ClubMeber扩展Person,正如您所建议的那样,并使用逐类表heriarchy映射策略


Blow,在选择某种继承策略时,您应该保留性能问题。您可以很好地了解可用的继承策略。不要忘记继承可以按如下方式作为关联重新写入

而不是

public class A {}

public class B extends A {}
你可以用

public class B {

    private A a;

}
或者可以使用MapedSuperClass映射所有继承的属性,而不使用任何Hibernate/JPA继承策略。看


请记住,在使用默认JPA/Hibernate注释时,Hibernate总是获取所有子类。如果您有一个单一层次结构,则更喜欢使用单一表继承策略。当您有一个复杂的层次结构时,Joined strategy的设计会更好,但在查询任何实体时,它会由于性能问题而受到影响。

对不起,我使用的是纯Hibernate/JPA,而不是NHibernate。。。所以你的建议是使用@OneToOne关系而不是继承,不是吗?我在实现它方面没有问题,但有点不合逻辑:)@blow:这确实是我的建议。但是,看看JPA,你可能会选择其他东西。对于您已经建议的连接策略,继承是相当简单的。但是也许有更多的JPA/Hibernate知识的人可以在这个问题上提供更多的信息。我相信你们已经知道了:?你们会有其他类扩展Person吗?@matt b:现在没有,但我会把Person放在一个表中,以便在其他项目中重复使用。TablePersClass在数据库中只做一个表,我会得到两个单独的表,Person和ClubMember,我需要一个人在一个单独的、清晰的表中重复使用pourpose。@我不明白为什么这会有区别,但是如果你必须有两个表,那么按照你将要使用的具体子类方法使用表。你的最后一段很有趣。这让我想起了为什么延迟加载如此重要,为什么它会因为过于智能的层次结构而变得令人讨厌,以及为什么使用字段聚合通常是更好的选择(读取更容易,维护更容易,延迟加载更容易,而不管关系的深度如何)。显然这对Hibernate和NHibernate都是正确的(逻辑上也是如此)。谢谢