父 - 子关系 - 自连接映射

时间:2017-04-04 08:05:04

标签: java spring hibernate jpa hibernate-mapping

我正在尝试构建一个应用程序,它将接收带有Employees列表的XML文件,并将父子/员工管理器关系存储在单个数据库表中。

我的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>

一名员工只能拥有一名经理,但一名经理可以拥有多名下属/员工。

解组收到的XML文件时没有麻烦但现在我正在尝试创建适当的模型,这样我就可以将未编组的值存储在数据库中。数据应存储在名为&#34; Employee&#34;的表中。并应包含以下数据:

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

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

由于我对此非常陌生,我已经用Google搜索了几个示例和教程(以及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

如果有人能指出我的方向来定义合适的模型,那将非常感激!

2 个答案:

答案 0 :(得分:2)

Hibernate中,当您想要映射ManyToOne关系时,您需要在实体之间而不仅仅是属性之间进行映射,因此您需要引用Employee类型的对象,而不仅仅是{ {1}}或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仅用于关系,不能与a一起使用 简单的列,你需要这样写:

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

  • 最重要的确保您使用@Transient映射您的课程,因此可以 坚持在数据库中。

示例:

您可以检查Hibernate Self Join Annotations One To Many mapping example它是否使用您要实施的相同型号。

答案 1 :(得分:-1)

您应该只是与Employee表有一个ManyToOne关系,即几个员工可以拥有相同的经理(也是一个员工),对于经理,这个字段将保持为空,如下所示:

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

    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    private Employee manager;

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