首页 文章

JPA中的继承策略

提问于
浏览
0

我刚接触JPA,所以初学者的问题:

  • 为什么Hibernate Provider会使用employees_employees创建第二个表?我的示例中的代码是创建第二个表的原因?

  • 为什么manager_id列成为员工的id列的fk?为什么我需要单表策略中的fk?

  • 为什么创建主键(屏幕截图中的金色)?

  • 在第二个表 employees_employees 中创建了department_id作为员工表中的fk到id,为什么?

  • 来自互联网的任何资源,以便了解这一点,将是HelpFul!

enter image description here

雇员:

@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 回答

  • 1

    由于您已选择 SINGLE_TABLE 作为继承策略,因此 EmployeeManager 都存储在同一个表中 .

    • 默认情况下,单向一对多关系(在您的情况下为 Employee.manager )由JPA在附加连接表的帮助下表示(就像多对多关系一样) . 在您的情况下,它恰好加入 employees 表自己 . 如果您想在源实体的表中使用外键,则需要使用 @JoinColumn

    • 这与第1点有关 . 你能用下面的代码解释一下你想要完成的事吗? Manager 已经有一个id(来自其父实体)

    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "manager_id" ,insertable = false , updatable = false)
    private int id;
    

    事件如果切换到使用 @JoinTableemployees 表中仍会有一个外键(你怎么想象 Employee - Manager 关系在数据库中表示?)

    • 由于以下代码:
    @Id
    @Column(name = "id")
    private int id;
    

    编辑

    要实现 Department has -a Manager 关系,您需要进行以下更改:

    @Entity
        public class Department {
            @Id
            private int id;
    
            @ManyToOne(mappedBy = "department")
            private Manager manager;
            ...
        }
    

    Department.manager 不是绝对必要的,但我've included it in case you wanted a bi-directional relationship (I didn' t注意到 Manager.department 字段已经在 Manager 中第一次读到你的代码了)

  • 0

    不确定你想要实现什么 . 但肯定你的代码看起来有点奇怪 .

    1)表employees_employees已创建,因为您已经提到管理器和部门之间的映射是一对多 . 一个表策略默认为一对一映射 .

    2)问题是你有2个同名id的变量;一个在employee表中,另一个在manager表中 .

    3)是正确的行为 . 您在员工类中使用了@id注释 . 因此创建了主键 .

    4)因为你使用了单表策略 . 部门上的超级父级是员工,因此部门的主要关键栏与员工的相同 . 所以department_id引用了employee表的id .

    5)告诉我们你想要达到的目标,我们可以帮助你 . 或者浏览一下hibernate教程 .

相关问题