在Hibernate中将多个类映射到一个表中,不需要使用DTYPE列

17

我有两个Hibernate类:一个基类和一个扩展类,扩展类具有其他表映射的附加字段。

例如,我有:

@Entity
@Table(name="Book")
public class A {
    private String ID;
    private String Name;
    // ...
}

@Entity
@Table(name="Book")
public class B extends A {
    public String node_ID;
    // ...
}

public class Node {
    public String ID; // maps to B.node_ID
    // ...
}
怎样在Hibernate中进行映射?Hibernate文档列出了三种继承配置:每个类对应一个表、一个带有类型列的表和一个连接表,但这些都不适用于此处情况。
我需要这么做的原因是,A类来自通用框架,可重复使用于多个项目,而B类(以及Node)是特定项目的扩展,它们将不再被使用。未来,我可能会有一个C类,其中包含house_ID或其他字段。 编辑:如果我尝试上面的伪代码配置(两个实体映射到同一张表),则会出现错误,报告找不到DTYPE列。HQL语句附加了“where DTYPE =”A”的条件。

如果这些类被映射到同一张没有鉴别器列的表中,Hibernate如何区分它们? - axtavt
@axtavt 这就是重点;每个 B 的实例也都是 A。 - ashes999
你有没有找到解决这个问题的有效方法? - membersound
2个回答

10

通过将@DiscriminatorColumn@DiscriminatorValue映射到两个类中相同的值,可以实现这一点;这可以来自于您使用的任何列,该列具有相同的数据,而不管类型是哪种(不确定是否适用于空值)。

这些类应该如下所示:

@Entity
@Table(name="Book")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="published")
@DiscriminatorValue(value="true")
public class A {
    private String ID;
    private String Name;
    // ...
}

@Entity
@Table(name="Book")
@DiscriminatorValue(value="true")
public class B extends A {
    public String node_ID;
    // ...
}

5
对我没有用,我得到了 org.hibernate.MappingException: Entities [B] and [A] are mapped with the same discriminator value 'true' 的错误。(如果有关系,Hibernate 版本为 5.3.7)。 - Yoory N.

0
对于像我一样来到这里并且不想要有dtype列,而是想要在同一个表中用于多个实体的人,我推荐使用this
基本上,你可以像这样创建一个基类。
@MappedSuperclass
public abstract class BaseBook<T extends BaseBook> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    ... any other variables, getters + setters
}

@Entity
@Table(name= "book")
public class BookA extends BaseBook<BookA>{ 
  //Default class no need to specify any variables or getters/setters
}

@Entity
@Table(name= "book")
public class BookB extends BaseBook<BookB>{ 
  @Column(name = "other_field")
  private String otherFieldInTableButNotMapedInBase

  ... Any other fields, getter/setter
}


从上面我们已经创建了基本的超级类,它没有任何实体或表映射。然后我们创建 BookA 作为默认的实体+表映射。从那里我们可以创建其他实体,都扩展自 BaseBook,但指向一个表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接