我刚接触JPA,所以初学者的问题:
-
为什么Hibernate Provider会使用employees_employees创建第二个表?我的示例中的代码是创建第二个表的原因?
-
为什么manager_id列成为员工的id列的fk?为什么我需要单表策略中的fk?
-
为什么创建主键(屏幕截图中的金色)?
-
在第二个表
employees_employees
中创建了department_id作为员工表中的fk到id,为什么? -
来自互联网的任何资源,以便了解这一点,将是HelpFul!
雇员:
@Entity
@Table (name = "employees")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "test" , discriminatorType = DiscriminatorType.STRING)
public class Employee {
public Employee(int id, String name, String lastname, double salary, String spec) {
this.id = id;
this.name = name;
this.salary = salary;
this.specialization = spec;
this.lastname = lastname;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
", spec='" + specialization + '\'' +
'}';
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
@Id
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "lastname")
private String lastname;
@Column(name = "salary")
private double salary;
@Column (name = "specialization")
private String specialization;
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
@OneToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE}, fetch = FetchType.EAGER)
private Manager manager;
public Employee(){}
}
经理:
@Entity
@DiscriminatorValue("M")
public class Manager extends Employee{
public Manager(){}
public Set<Departments> getDepartment() {
return department;
}
public void setDepartment(Set<Departments> department) {
this.department = department;
}
public String getManager_country() {
return manager_country;
}
public void setManager_country(String manager_country) {
this.manager_country = manager_country;
}
public String getManager_address() {
return manager_address;
}
public void setManager_address(String manager_address) {
this.manager_address = manager_address;
}
public String getManager_experience() {
return manager_experience;
}
public void setManager_experience(String manager_experience) {
this.manager_experience = manager_experience;
}
@Override
public String toString() {
return "Manager{" +
"department=" + department +
", manager_address='" + manager_address + '\'' +
", manager_experience='" + manager_experience + '\'' +
", manager_country='" + manager_country + '\'' +
", id=" + id +
'}';
}
@OneToMany(fetch = FetchType.EAGER , cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE} )
private Set<Departments> department;
//private Employee employee;
public Manager(String manager_experience,String manager_address, String manager_country) {
this.manager_experience = manager_experience;
this.manager_address = manager_address;
this.manager_country = manager_country;
}
@Column(name = "experience")
private String manager_experience;
@Column(name = "address")
private String manager_address;
@Column(name = "country")
private String manager_country;
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "manager_id" ,insertable = false , updatable = false)
private int id;
}
部门:
@Entity
@DiscriminatorValue("D")
public class Departments extends Manager{
public String getSales() {
return sales;
}
public void setSales(String sales) {
this.sales = sales;
}
public String getCostumer_support() {
return costumer_support;
}
public void setCostumer_support(String costumer_support) {
this.costumer_support = costumer_support;
}
public String getDevelopers() {
return developers;
}
public void setDevelopers(String developers) {
this.developers = developers;
}
public String getSystem_administrators() {
return system_administrators;
}
public void setSystem_administrators(String system_administrators) {
this.system_administrators = system_administrators;
}
public String getAccounting_department() {
return accounting_department;
}
public void setAccounting_department(String accounting_department) {
this.accounting_department = accounting_department;
}
//private Manager manager;
@Column(name = "costumer_support_department" , unique = false, updatable = true , insertable = true , nullable = true)
private String costumer_support;
@Column(name = "developers_department" , unique = false, updatable = true , insertable = true , nullable = true)
private String developers;
@Column(name = "sys_admins_department" , unique = false, updatable = true , insertable = true , nullable = true)
private String system_administrators;
@Column(name = "accounting_department" , unique = false, updatable = true , insertable = true , nullable = true)
private String accounting_department;
@Column(name = "sales_department" , unique = false, updatable = true , insertable = true , nullable = true)
private String sales;
public Departments(){}
}
2 回答
由于您已选择
SINGLE_TABLE
作为继承策略,因此Employee
和Manager
都存储在同一个表中 .默认情况下,单向一对多关系(在您的情况下为
Employee.manager
)由JPA在附加连接表的帮助下表示(就像多对多关系一样) . 在您的情况下,它恰好加入employees
表自己 . 如果您想在源实体的表中使用外键,则需要使用@JoinColumn
这与第1点有关 . 你能用下面的代码解释一下你想要完成的事吗?
Manager
已经有一个id(来自其父实体)事件如果切换到使用
@JoinTable
,employees
表中仍会有一个外键(你怎么想象Employee
-Manager
关系在数据库中表示?)好问题 . 我想它是因为
Department
是Manager
,当Employee.manager
实际指向Department
时,JPA需要这种方式 . 为什么要从Manager
继承Department
?Department
有Manager
(@OneToOne/@ManyToOne
)是不是更符合逻辑?你知道,这会简化事情https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_OneToMany_using_a_JoinTable_database https://en.wikibooks.org/wiki/Java_Persistence/Inheritance(这些确实是谷歌的最佳成绩......)
编辑
要实现
Department
has -aManager
关系,您需要进行以下更改:Department.manager
不是绝对必要的,但我've included it in case you wanted a bi-directional relationship (I didn' t注意到Manager.department
字段已经在Manager
中第一次读到你的代码了)不确定你想要实现什么 . 但肯定你的代码看起来有点奇怪 .
1)表employees_employees已创建,因为您已经提到管理器和部门之间的映射是一对多 . 一个表策略默认为一对一映射 .
2)问题是你有2个同名id的变量;一个在employee表中,另一个在manager表中 .
3)是正确的行为 . 您在员工类中使用了@id注释 . 因此创建了主键 .
4)因为你使用了单表策略 . 部门上的超级父级是员工,因此部门的主要关键栏与员工的相同 . 所以department_id引用了employee表的id .
5)告诉我们你想要达到的目标,我们可以帮助你 . 或者浏览一下hibernate教程 .