【问题标题】:JPA/Hibernate inheritance with multiple levels and tables.具有多个级别和表的 JPA/Hibernate 继承。
【发布时间】:2012-01-10 05:57:04
【问题描述】:

所以我有这个结构。

表 1 ID 字段1 字段2 鉴别器值

表2 ID 字段3

表 3 ID 字段4

我想使用继承如下。

@DiscriminatorColumn("discriminatorValue")
@Entity
@Inheritance
@Table("Table1")
public class T1  {

@Id
private int id;
...

private String field1;
..
private String field2;
..
}

@SecondaryTable(name = "Table2", pkJoinColumns = {@PrimaryKeyJoinColumn(name = "id",     referencedColumnName = "id")})
@DiscriminatorValue("tbl2")
@Entity
public class T2 extends T1 {

private String field3;
..
}

@SecondaryTable(name = "Table3", pkJoinColumns = {@PrimaryKeyJoinColumn(name = "id",     referencedColumnName = "id")})
@DiscriminatorValue("tbl3")
@Entity
public class T3 extends T2 {

private String field4;
..
}

我发现当我尝试保存 T3 对象时,不会包含 T2 中的辅助表。

谢谢

【问题讨论】:

  • 它适用于 T2 吗? T3 会保存 T1 而不是 T2 吗?
  • 是的,除了因为 T2 不存在,T2 和 T3 上的 id 字段之间的外键链接失败。所以生成的sql看起来像这样。插入 T1(...) 插入 T3(...) 并没有生成 T2 插入。

标签: java hibernate inheritance jpa annotations


【解决方案1】:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Project {
  @Id
  private long id;
}


@Entity
@Table(name="LARGEPROJECT")
public class LargeProject extends Project {
  private BigDecimal budget;
}

【讨论】:

  • 欢迎来到 SO。请解释您的代码的作用以及它如何解决问题。 stackoverflow.com/help/how-to-answer
  • 如果想要有更多具有相同变量的表,例如 (user,admin)。您可以创建另一个抽象类来共享这些值。
【解决方案2】:

想通了。如果辅助表的任何字段中都没有数据,则不会插入该行。

所以在我的例子中,field3 没有数据,所以 T2 没有被插入,并且由于 T3 中的辅助表链接到 T2 中的行,所以整个事情都崩溃了。

哦,我发现的另一件事是,您不能在中间表中的字段上设置默认值来尝试强制创建它。 IE。做任何一个

private String field2 = "test";

public T2(){
  setField2("test");
}

没用。

谢谢

【讨论】:

    【解决方案3】:

    看起来您正在使用SINGLE_TABLE 继承策略,但明确地将子类中的一些属性拆分到单独的表中,而不是使用joined-subclass 策略。

    这似乎是混合继承策略的标准方法

    见: How to mix inheritance strategies with JPA annotations and Hibernate?

    Mapping multi-Level inheritance in Hibernate with Annotations

    您可能缺少的一件事是指定哪些字段转到哪些列。 @SecondaryTable 不依赖于继承层次结构 - 您可以在单个类中使用它 - 因此您必须明确指定子类中的字段映射到辅助表。

    因此在T2 你可能需要

    @Column(table="tbl2")
    private String field3;
    

    T3

    @Column(table="tbl3")
    private String field4;
    

    祝你好运!

    【讨论】:

    • 谢谢,我基本上使用的是单表,使用如何混合继承文章中的辅助表。我在相关字段上也有 @Column 注释。实际上,我在应用程序的另一部分中只使用一级 SecondaryTables 来执行此操作,并且效果很好,只是当您有 2 个 SecondaryTables 时,中间的一个才会消失。正如我现在提到的那样,这实际上是有道理的,因为 SecondaryTable 的注释可能被 T3 类覆盖......问题是我不确定如何解决这个问题。
    • 哦,我这样做的原因是有一堆不同的类从主要的 T1 类子类化。实际的类是 Control - 包含一堆关于控件的数据 Panel - 包含一个布局样式字段。页 - 包含页码。 ... 等等。
      我可能只是删除页面表并将页面信息放入面板表中,但从数据库中不太清楚,因为它看起来像一个面板上有一个页码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    相关资源
    最近更新 更多