我刚接触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(){}
}
答案 0 :(得分:1)
由于您已选择SINGLE_TABLE
作为继承策略,因此Employee
和Manager
都存储在同一个表中。
默认情况下,单向一对多关系(在您的情况下为Employee.manager
)由JPA在附加联接表的帮助下表示(就像多对多关系一样)。在您的情况下,它恰好加入employees
表自己。如果您想在源实体表中使用外键,则需要使用@JoinColumn
这与第1点有关。你能用下面的代码解释一下你想要完成的事吗? Manager
已经有一个id(来自其父实体)
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "manager_id" ,insertable = false , updatable = false)
private int id;
如果您切换到使用@JoinTable
的事件,employees
表格中仍会有外键(您认为Employee
- Manager
关系怎么样?在数据库中表示?)
由于以下代码:
@Id
@Column(name = "id")
private int id;
好问题。我认为这是因为Department
是一个Manager
,当Employee.manager
实际指向Department
时,JPA需要这种方式。为什么要让Department
继承Manager
? Department
有一个Manager
(@OneToOne/@ManyToOne
)更合乎逻辑吗?这会简化事情,你知道
修改
要实施Department
has-a Manager
关系,您需要进行以下更改:
@Entity
public class Department {
@Id
private int id;
@ManyToOne(mappedBy = "department")
private Manager manager;
...
}
Department.manager
并非绝对必要,但我已将其包含在内,以防您想要双向关系(我没有注意到Manager.department
字段已经在{ {1}}我第一次读你的代码时)
答案 1 :(得分:0)
不确定你想要实现的目标。但肯定你的代码看起来有点奇怪。
1)表employees_employees已经创建,因为您已经提到管理器和部门之间的映射为一对多。一个表策略默认为一对一映射。
2)问题是你有2个同名id的变量;一个在employee表中,另一个在manager表中。
3)是正确的行为。您在员工类中使用了@id注释。因此创建了主键。
4)因为你使用了单表策略。部门的超级父级是员工,因此部门的主要关键栏与员工的主要关键栏相同。所以department_id引用了employee表的id。
5)告诉我们您想要达到的目标,我们可以为您提供帮助。或者浏览一下hibernate教程。