【问题标题】:Mapping multi-Level inheritance in Hibernate with Annotations在 Hibernate 中使用注解映射多级继承
【发布时间】:2009-12-10 20:37:27
【问题描述】:

以本题所列情况为例:

Mapping multi-Level inheritance in Hibernate

如何使用 Annotations 而不是 hbm 文件来完成此映射?

【问题讨论】:

    标签: hibernate inheritance


    【解决方案1】:

    您遇到的具体问题是什么?映射类层次结构via joined subclasses 非常简单:

    @Entity
    @Inheritance(strategy=InheritanceType.JOINED)
    public class A implements Serializable { ... }
    
    @Entity
    public class B extends A { ... }
    
    @Entity
    @PrimaryKeyJoinColumn(name="A_ID")
    public class C extends A { ... }
    
    @Entity
    @PrimaryKeyJoinColumn(name="B_ID")
    public class D extends B { ... }
    

    更新(基于 Michal 的评论)。

    如果您确实想使用鉴别器(并且您应该有好的理由这样做),可以将table-per-class-hierarchy strategysecondary tables 混合使用:

    @Entity
    @Table(name="A_table")
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="entity_type")
    @DiscriminatorValue("A")
    public class A implements Serializable { ... }
    
    @Entity
    @SecondaryTable(name="B_table")
    public class B extends A { ... }
    
    @Entity
    @SecondaryTable(name="C_table", pkJoinColumns={
        @PrimaryKeyJoinColumn(name="A_ID", referencedColumnName="ID")
    ))
    public class C extends A { ... }
    
    @Entity
    @SecondaryTable(name="D_table", pkJoinColumns={
        @PrimaryKeyJoinColumn(name="B_ID", referencedColumnName="ID")
    ))
    public class D extends B { ... }
    

    这种方法的缺点是您必须为每个映射的属性显式指定表:

    public class D extends B {
      @Column(table="D_table")
      private String someProperty;
    
      ...
    }
    

    【讨论】:

    • 我认为这不是问题所在。据我了解,他想使用鉴别器列。这就是我回答的原因,买你在这里的声誉要高得多,所以我很可能是错的:-)
    • @Michal - OP 没有在任何地方提到鉴别器。他链接到的问题说,鉴别器的使用是出于历史原因,但没有说他想继续使用它们。无论如何,如果 OP 确实想使用鉴别器,这很容易实现 - 我已经更新了我的答案以显示一个示例。
    • 原来我走在正确的轨道上,但我的 hbm 中有一个更基本的问题,导致我的注释无法被拾取。无论如何,感谢您的明确回答。干杯!
    • 有一个问题,你为什么说“你应该有一个好的理由”来使用鉴别器?我们的应用程序不止一种使用鉴别器将类映射到单个表。似乎工作得很好。你提到的缺点是什么?
    • 使用 table-per-hierarchy 策略很好;缺点是每行中有多个空值(并且无法对非根类进行非空约束)。使用 table-per-concrete-class 策略也很好;缺点是加入。当您将两者结合起来时,您会得到两全其美的结果,而且很少有理由这样做。
    【解决方案2】:

    Inheritance between @Entity annotated classes 被自动拾取。因此,如果您对 A 类进行了注解,并且 B 类也使用 @Entity 进行了注解并扩展了 A,并且 C 扩展了 B 并且也使用了@Entity 进行了注解,那么所有将被拾取。

    我没有使用结合了鉴别器值的连接子类,但我确信它与在 XML 中所做的非常相似(使用 @DiscriminatorColumn 和 @DiscriminatorValue)

    【讨论】:

    • 这是不正确的。您提到的隐式多态性与实际映射类层次结构之间存在很大差异。
    • 您能详细说明一下这个说法吗?我不知道我在暗示隐式多态性,而不是我打算这样做。我想描述一个层次结构 A
    • “@Entity 注释类之间的继承是自动获取的”——这是隐式多态性。为了映射实际的类层次结构,您必须使用@Inheritance 显式注释根类(加上根据选择的策略使用额外的注释)。
    【解决方案3】:

    这正是对我有用的东西:

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @DiscriminatorColumn(name="LoanType",discriminatorType="String")
    @Table(name = "A")
    public class A implements Serializable{
    }
    
    @Entity
    @Table(name= "B")
    @PrimaryKeyJoinColumn(name = "B_ID", referencedColumnName ="A_ID")
    public class B extends A{
    }
    
    
    @Entity
    @Table(name= "C")
    @PrimaryKeyJoinColumn(name = "C_ID", referencedColumnName = "B_ID")
    public class C extends B{}
    

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 2017-12-07
      • 2011-11-22
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 2017-02-15
      • 2015-02-08
      • 1970-01-01
      相关资源
      最近更新 更多