继承策略的架构设计 Table Per Class

Schema design for inheritance strategy Table Per Class

我正在尝试设计一个数据库模式,以便它适用于 Hibernate's Table Per Class 继承策略。因此,我不会让 Hibernate 生成 tables,而是我需要自己在 Liqibase 中设计它们,但这样 Hibernate 就可以使用它们来实现该策略。

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

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;

}

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

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

2) 我什至需要数据库中的车辆 table,因为它实际上永远不会用作实体(而只是一个抽象 class)?

如果有人能帮我解决这个问题,我将不胜感激。

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

在这种情况下,由于您的实体 class 是具体的,因此会生成 Vehicle table。您需要将 class 定义为抽象。

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

创建唯一 ID

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

Now, I know that [the table-per-concrete-class] strategy means that all the fields are in all tables,

嗯,不,你似乎很困惑。使用 InheritanceType.TABLE_PER_CLASS,每个具体实体 class E 映射到 table,其中包含对应于 E 的所有字段的列,包括继承的字段,但不包括非 E.

的超class实体的字段

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

另请注意,您的 Vehicle 实体包含与其子class 实体同名的字段,这很奇怪。 Java 字段不是多态的,因此这不太可能是您想要的。这当然是不必要的。

but I am not sure about two things.

1) Do I need to include the ID in the derived tables?

假设您坚持使用 TABLE_PER_CLASS,是的,每个实体 table 需要为相应实体 class 的每个持久性 属性 提供一个列,包括那些继承自 superclasses。这包括 id.

2) Do I even need a Vehicle table in the DB, since it will actually never be used as an entity (rather just an abstract class)?

如果您实际声明它就不会 abstract,但如果您让它具体化,那么是的,您需要一个 table。这是有道理的,因为在那种情况下,您可以拥有既不是 Car 也不是 BikeVehicle 个实体。