Java JPA/Hibernate-InheritanceType.JOINED的行为类似于InheritanceType.TABLE\u PER\u类

Java JPA/Hibernate-InheritanceType.JOINED的行为类似于InheritanceType.TABLE\u PER\u类,java,hibernate,jpa,Java,Hibernate,Jpa,我试图在Hibernate中实现一个非常简单的继承模型。基本上,我有一个可以称为a的超类和几个子类,所有这些子类都继承自a。因为我看到的行为对所有人都是一样的,所以它们可以被称为B 我想要达到的是第6.2节所描述的。基本上,应该有一个包含字段的a表,和一个只包含子类不同字段的B表,以及一个返回到a表的联接列。我正在使用Hibernate的自动模式生成(仅为开发持久性单元启用) 然而,当我查看模式时,我看到的是a的表包含其字段(正确),以及B的表,其中包含a中的所有字段(不正确),以及B中添加的字

我试图在Hibernate中实现一个非常简单的继承模型。基本上,我有一个可以称为
a
的超类和几个子类,所有这些子类都继承自
a
。因为我看到的行为对所有人都是一样的,所以它们可以被称为
B

我想要达到的是第6.2节所描述的。基本上,应该有一个包含字段的
a
表,和一个只包含子类不同字段的
B
表,以及一个返回到
a
表的联接列。我正在使用Hibernate的自动模式生成(仅为开发持久性单元启用)

然而,当我查看模式时,我看到的是
a
的表包含其字段(正确),以及
B
的表,其中包含
a
中的所有字段(不正确),以及
B
中添加的字段。我的课程注释如下:

@Entity
@Table(name="A")
@Inheritance(strategy = InheritanceType.JOINED)
public class A implements Serializable {
    protected long id;
    protected Date createDate;
    protected String title;
    protected boolean hidden;

    public A() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    public Date getCreateDate() {
        return createDate;
    }

    @Column(nullable = false)
    public boolean isHidden() {
        return hidden;
    }

    @Column(nullable = false)
    public String getTitle() {
        return title;
    }

    //also setters...   
}

@Entity
@Table(name="B")
@PrimaryKeyJoinColumn(name="aId", referencedColumnName="id")
public class B extends A {
    private String extraField;

    public B() {
        super();
    }

    @Column
    public String getExtraField() {
        return extraField;
    }

    //also setter...
}
知道我做错了什么吗?具体来说,当我查看生成的DB模式时,我希望看到的是:

Table A:  {id, createDate, title, hidden}
Table B:  {aId, extraField}
…相反,我得到的是:

Table A:  {id, createDate, title, hidden}
Table B:  {id, createDate, title, hidden, extraField}

使用Hibernate的自动模式生成是不可能的,还是我把注释搞砸了?

您的注释是正确的,它应该生成您想要的表模式

但是现在您得到了一个不需要的模式,它正是使用每个具体类的
策略(即
@heritance(strategy=heritancetype.Table\u per\u class)
)生成的模式。因此,我认为可能的原因之一是配置中的
hibernate.hbm2ddl.auto
属性使用默认值,即
update

update
值的行为是:

  • Hibernate将尝试创建一个 更新脚本以更新数据库 架构到当前映射时 将创建
    SessionFactory

  • 如果无法创建update语句 执行时,将跳过该操作(对于 将NOTNULL列添加到 表(包含现有数据)

  • Hibernate不会删除任何数据 在更新期间。(例如,如果 列的名称被更改,它只是 添加具有新名称的新列, 但仍保留列中的 (原名)

因此,我认为您必须使用
@heritance(strategy=InheritanceType.TABLE\u PER\u CLASS)
来生成之前的模式,该模式生成了以下模式。表A和表B彼此之间没有任何外键关联

Table A:  {id, createDate, title, hidden}
Table B:  {id, createDate, title, hidden, extraField}
之后,您改为使用
@heritance(strategy=heritancetype.JOINED)
。在更新架构的过程中,hibernate通过在
TableA.id
TableB.id
之间添加一个外键关联来更新您的架构。它将所有其他列保留在表B中。这就是为什么即使注释是正确的,也会得到当前模式


在启动hibernate程序之前,从DB中删除表A和表B后,应生成所需的表架构。或者,您可以将
hibernate.hbm2ddl.auto
设置为
create
,然后hibernate将在生成表架构之前删除所有表。

谢谢,我想我从来没有使用过
InheritanceType.table\u PER\u CLASS
,但是在任何情况下,删除表并让Hibernate按照您建议的方式重新生成模式都是固定的。