gpt4 book ai didi

java - JPA/Hibernate - InheritanceType.JOINED 的行为类似于 InheritanceType.TABLE_PER_CLASS

转载 作者:搜寻专家 更新时间:2023-11-01 02:53:44 27 4
gpt4 key购买 nike

我正在尝试在 Hibernate 中实现一个非常简单的继承模型。基本上我有一个可以称为 A 的父类(super class),以及几个继承自 A 的子类。由于我看到的行为对所有这些行为都是相同的,因此可以将它们称为 B

我想要达到的是所描述的here在第 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...
}

知道我做错了什么吗?具体来说,当我查看生成的数据库模式时,我想看到的是:

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

...而我得到的是:

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

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

最佳答案

您的注释是正确的,它应该会生成您想要的表架构。

但现在您得到了一个不需要的模式,这正是使用 Table per concrete class 策略生成的模式(即 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)) .因此,我认为可能的原因之一是您配置中的 hibernate.hbm2ddl.auto 属性使用了默认值,即 update

update 值的行为是:

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

  • 如果不能更新语句执行,它将被跳过(对于示例向 a 添加一个非空列现有数据表)

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

因此,我认为您必须使用 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 生成之前的模式,它产生了以下模式。表 A 和表 B 之间没有任何外键关联。

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

在那之后,您改为使用 @Inheritance(strategy = InheritanceType.JOINED)。在更新架构过程中, hibernate 刚刚通过在 TableA.idTableB.id 之间添加外键关联来更新您的架构。它保留了表 B 中的所有其他列。这就是为什么即使您的注释是正确的,您仍会获得当前模式的原因。

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

关于java - JPA/Hibernate - InheritanceType.JOINED 的行为类似于 InheritanceType.TABLE_PER_CLASS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6027785/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com