继承策略的架构设计 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
也不是 Bike
的 Vehicle
个实体。
我正在尝试设计一个数据库模式,以便它适用于 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
.
这与 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
也不是 Bike
的 Vehicle
个实体。