smi*_*tan 1 java hibernate jpa
我正在开始使用 Hibernate,有一个关于 InheritanceType.JOINED 和 @PrimaryKeyJoinColumn 的问题。
给定以下数据库表,其中员工引用人员,经理引用员工:
create table person (person_id int(10) auto_increment,
name varchar(100),
primary key (person_id));
create table employee (employee_id int(10) auto_increment,
person_id int(10),
salary int(10),
primary key (employee_id));
create table manager (manager_id int(10) auto_increment,
employee_id int(10),
shares int(10),
primary key (manager_id));
Run Code Online (Sandbox Code Playgroud)
我可以为 Person 和 Employee 创建前两个类,如下所示:
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue
@Column(name="person_id")
private int personId;
@Column(name="name")
private String name;
}
@Entity
@Table(name="employee")
@PrimaryKeyJoinColumn(name="person_id")
public class Employee extends Person {
@GeneratedValue
@Column(name="employee_id")
private int employeeId;
@Column(name="salary")
private int salary;
}
Run Code Online (Sandbox Code Playgroud)
当谈到 Manager 类时,我不确定 @PrimaryKeyJoinColumn 使用哪个值。通过阅读 JPA 规范,我应该在整个超类/子类/子类层次结构中仅使用一个 id,我怀疑应该是 person_id。
我应该从经理表中删除employee_id列并将其替换为person_id吗?我问的原因是,在数据库中拥有“级联”主键似乎很自然(即经理不直接引用人员),但我相信 Hibernate 要求所有子子类(无论“深”)都包含一个外键返回到超类。对我的断言进行一些确认将非常有用。
您可以使用任何您想要的列名称。
@PrimaryKeyJoinColumn注释用于告诉hibernate连接表中外键列的名称是什么。
@Entity
@Table(name = "manager")
@PrimaryKeyJoinColumn(name = "employee_id")
public class Manager extends Employee{
private String branch;
}
Run Code Online (Sandbox Code Playgroud)
此代码意味着在manager表中您有一个名为的列employee_id,它是表的外键employee。
此注释是可选的,因此如果您不提供它,那么外键列名称将与基类中的键名称相同(如果多级继承则为超级基),在您的情况下,如果您不提供,则任何子类都会作为person_id外键。
employee_id如果您想保留表中的字段名称,manager那么您必须像这样提供。
@PrimaryKeyJoinColumn(name="employee_id")
如果您根本不提供此注释,那么将会有一个列名person_id用作employee表的外键。
这是文档所说的。
此注释指定一个主键列,该主键列用作连接到另一个表的外键。
用于将JOINED映射策略中实体子类的主表连接到其超类的主表;它在SecondaryTable注释中使用,将辅助表连接到主表;它可以用在 OneToOne 映射中,其中引用实体的主键用作被引用实体的外键。
如果在 JOINED 映射策略中没有为子类指定 PrimaryKeyJoinColumn 注解,则假定外键列与超类主表的主键列同名
编辑
当我尝试通过 id 检索管理器时,Hibernate 正在执行查询。
select
manager0_.id as id1_4_0_,
manager0_2_.name as name2_4_0_,
manager0_1_.employee_id as employee1_1_0_,
manager0_1_.salary as salary2_1_0_,
manager0_.branch as branch1_2_0_
from
manager manager0_
inner join
employee manager0_1_
on manager0_.id=manager0_1_.id
inner join
person manager0_2_
on manager0_.id=manager0_2_.id
where
manager0_.id=?
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,经理有员工的外键,而不是人员表。我还没有创建表。我用的是hbm2ddl=create.
这意味着 Hibernate 本身使用级联主键而不是仅使用超级父键创建表。
我理解您的困惑,即使我在 hibernate文档中找不到任何内容。它只是说 FK 将指向超类主键。它不指定直接超类或顶级超类。虽然我检查了其他 JPA 实现,即OpenJPA。它确实明确指出 FK 指向直接超类。
| 归档时间: |
|
| 查看次数: |
14756 次 |
| 最近记录: |