继承策略的模式设计每类表

时间:2018-02-07 19:02:55

标签: java hibernate jpa liquibase

我正在尝试设计数据库架构,以使其适用于Hibernate's Table Per Class继承策略。所以,我不会让Hibernate生成表格,而是我需要在Liqibase中自己设计它们,但是Hibernate可以将它们与策略一起使用。

我的实体类应该是这样的。

Vehicle.java

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {

    @Id @GeneratedValue
    private int id;

    private String name;

    private String brand;

}

Car.java

@Entity
public class Car extends Vehicle {

    private String oil;

}

Bike.java

@Entity
public class Bike extends Vehicle {

    private String frame;

}

现在,我知道这个策略意味着所有表都在所有表中,但我不确定两件事。

1)我是否需要在派生表中包含ID?

2)我是否甚至需要DB中的Vehicle表,因为它实际上永远不会被用作实体(而只是一个抽象类)?

如果有人能为我清楚,我会很感激。

2 个答案:

答案 0 :(得分:1)

  

现在,我知道[每个具体的表格]策略意味着所有字段都在   所有表格,

不,你似乎很困惑。使用InheritanceType.TABLE_PER_CLASS,每个具体实体类E映射到一个表,该表包含与E的所有字段对应的列,包括继承的,但不包括实体的字段不是E 的超类。

这与InheritanceType.SINGLE_TABLE形成对比,其中整个继承层次结构中的所有实体类型都映射到同一个表,然后该层必须包含层次结构中每个实体的每个属性的列(不重复继承)字段)。

另请注意,您的Vehicle实体包含的字段与其子类的字段具有相同的名称,这很奇怪。 Java字段不是多态的,所以这不太可能是你想要的。这当然没必要。

  

但我不确定两件事。

     

1)我是否需要在派生表中包含ID?

假设您坚持使用TABLE_PER_CLASS,是的,每个实体表都需要为相应实体类的每个持久属性提供一个列,包括从超类继承的那些。这包括id

  

2)我甚至需要DB中的Vehicle表,因为它实际上是   永远不会被用作实体(而只是一个抽象类)?

如果您确实声明它abstract,那就不是了,但是如果你具体说明,那么是的,你需要一个表格。这是有道理的,因为在这种情况下,您可以拥有既不Vehicle也不Car的{​​{1}}个实体。

答案 1 :(得分:0)

如果您正确地注释实体,Hibernate模式生成工具应该能够生成您的模式。

在这种情况下,由于您的实体类具体而生成的Vehicle表。您需要将类定义为抽象。

超类中定义的所有字段(包括@Id)都将复制到相应的子类表中。关于id自动生成有一个限制。您不能将每个类继承策略的表与GenerationType.IDENTITY策略一起使用,因为生成的键在所有表中应该是唯一的。身份为每个表创建唯一ID

确保Generation.AUTO策略未映射到RDBMS的IDENTITY策略(您可以明确指定策略,例如GenerationType.TABLE以覆盖默认值)