父 - 子关系 - 自连接映射

Parent - Child relationship - self join mapping

我正在尝试构建一个应用程序,它将接收包含员工列表的 XML 文件并将 parent-child/employee-manager 关系存储在单个数据库 table.[=14= 中]

我的 XML 文件如下所示:

<Employees>
    <Employee manager="Patrick">Martin</Employee>
    <Employee manager="Patrick">Kent</Employee>
    <Employee manager="Martin">Mark</Employee>
    <Employee>Hugo</Employee> <!-- root element of the employee-manager tree -->
    <Employee manager="Hugo">Osa</Employee>
    <Employee manager="Osa">Patrick</Employee>
</Employee>

一个员工只能有一个经理,但是一个经理可以有多个subordinates/employees。

我在解组接收到的 XML 文件时没有遇到任何问题,但现在我正在尝试创建适当的模型,以允许我将解组后的值存储在数据库中。数据应存储在名为 "Employee" 的 table 中,并应包含以下数据:

------------------------------
| id            | Integer    |
------------------------------
| employee_name | String     |
------------------------------
| parent_id     | Integer    | -- reference to the manager
------------------------------

我创建了一个名为 Employee 的新 class,但我不确定如何定义适当的 ManyToOne/OneToMany 注释。

因为我对此还很陌生,所以我在谷歌上搜索了几个示例和教程(以及 Stack Overflow 上类似问题的答案),但我想我在这方面犯了一些大错误定义此模型时的此实现。我最近的尝试是这样的:

public class Employee {
    @Id
    @GeneratedValue
    private int id;

    @Column(name = "parent_id")
    @Transient
    @ManyToOne(cascade={CascadeType.ALL})
    private String managerName;

    @Column(name = "employee_name")
    @JoinColumn(name="parent_id")
    private String employeeName;

    // getters and setters

如果有人能指出我定义适当模型的方向,我将不胜感激!

Hibernate 中,当您想要映射 ManyToOne 关系时,您将其映射到实体之间,而不仅仅是属性,因此您需要引用类型为 Employee 的对象,而不仅仅是一个 String 或一个 id.

问题:

  • 所以你的映射不正确,会抛出很多映射错误, 而不是写:

    @Column(name = "parent_id")
    @Transient
    @ManyToOne(cascade={CascadeType.ALL})
    private String managerName;
    

    您需要像这样映射 ManyToOne 关系:

    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Employee manager;
    
  • 并确保像这样映射关系的另一端:

    @OneToMany(mappedBy="manager")
    private Set<Employee> subordinates = new HashSet<Employee>();
    
  • 您对列 employee_name 的映射也不正确, @JoinColumn 仅用于关系,不能与 简单的专栏,你需要这样写:

    @Column(name = "employee_name")
    private String employeeName;
    
  • @Transient在你的映射中没有用,我们只有在需要时才使用它 想要使用不会保留在数据库中的属性。

  • 最重要的确保将class映射到@Entity,这样它就可以 持久化在数据库中。

示例:

您可以检查 Hibernate Self Join Annotations One To Many mapping example 它使用了您要实现的相同模型。

您应该简单地与您的员工 table 建立多对一关系,即多个员工可以拥有同一个经理(他也是员工),对于经理,此字段将保持为空,如下所示:

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    private Employee manager;

    @Column(name = "employee_name")
    private String employeeName;