我正在尝试设计数据库架构,以使其适用于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表,因为它实际上永远不会被用作实体(而只是一个抽象类)?
如果有人能为我清楚,我会很感激。
答案 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以覆盖默认值)