【问题标题】:Parent - Child relationship - self join mapping父-子关系-自联接映射
【发布时间】:2017-08-29 07:42:38
【问题描述】:

我正在尝试构建一个应用程序,该应用程序将接收包含员工列表的 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 文件时我没有遇到任何问题,但现在我正在尝试创建适当的模型,以便我将解组后的值存储在数据库中。数据应存储在名为“Employee”的表中,并应包含以下数据:

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

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

【问题讨论】:

    标签: java spring hibernate jpa hibernate-mapping


    【解决方案1】:

    Hibernate 中,当您想要映射ManyToOne 关系时,您会在实体之间而不只是属性之间进行映射,因此您需要引用Employee 类型的对象,而不仅仅是String 或@987654326 @。

    问题:

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

      @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 在你的映射中没有用,我们只在我们使用它时使用它 想要使用不会在数据库中持久化的属性。

    • 并且最重要的确保您将您的班级映射到@Entity,这样它就可以 保存在数据库中。

    示例:

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

    【讨论】:

    • 谢谢,chsdk。我将尝试按照您提出的方式实施解决方案。希望我能成功。
    • @hezus 不客气,我相信它会给你预期的结果。
    【解决方案2】:

    您应该简单地与您的 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;
    

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 2011-01-17
      相关资源
      最近更新 更多