Java 父子关系-自联接映射

Java 父子关系-自联接映射,java,spring,hibernate,jpa,hibernate-mapping,Java,Spring,Hibernate,Jpa,Hibernate Mapping,我正在尝试构建一个应用程序,它将接收包含员工列表的XML文件,并将父-子/员工-经理关系存储在单个数据库表中 我的XML文件如下所示: <Employees> <Employee manager="Patrick">Martin</Employee> <Employee manager="Patrick">Kent</Employee> <Employee manager="Martin">Mark&

我正在尝试构建一个应用程序,它将接收包含员工列表的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>
我创建了一个名为
Employee
的新类,但我不确定如何定义适当的多通/OneToMany注释

由于我对这方面还不太熟悉,所以我在谷歌上搜索了一些示例和教程(以及关于堆栈溢出的类似问题的答案),但我想我在定义这个模型时在这个实现中犯了一些大错误。我最近的尝试如下所示:

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
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="manager_id")
private Employee manager;
@OneToMany(mappedBy="manager")
private Set<Employee> subordinates = new HashSet<Employee>();
@Column(name = "employee_name")
private String employeeName;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    private Employee manager;

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

如果有人能为我指出定义合适模型的方向,我将非常感谢

Hibernate
中,当您想要映射
manytone
关系时,您需要在实体之间映射它,而不仅仅是属性,因此您需要引用
Employee
类型的对象,而不仅仅是
字符串或
id

问题:

  • 因此,您的映射不正确,会引发许多映射错误, 而不是写:

    @Column(name = "parent_id")
    @Transient
    @ManyToOne(cascade={CascadeType.ALL})
    private String managerName;
    
    您需要像这样映射
    manytone
    关系:

    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
    
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Employee manager;
    
    @OneToMany(mappedBy="manager")
    private Set<Employee> subordinates = new HashSet<Employee>();
    
    @Column(name = "employee_name")
    private String employeeName;
    
    @Entity
    @Table(name = "EMPLOYEE")
    public class Employee {
    
        @Id
        @GeneratedValue
        private int id;
    
        @ManyToOne
        private Employee manager;
    
        @Column(name = "employee_name")
        private String employeeName;
    
  • 并确保映射关系的另一面,如下所示:

    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
    
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Employee manager;
    
    @OneToMany(mappedBy="manager")
    private Set<Employee> subordinates = new HashSet<Employee>();
    
    @Column(name = "employee_name")
    private String employeeName;
    
    @Entity
    @Table(name = "EMPLOYEE")
    public class Employee {
    
        @Id
        @GeneratedValue
        private int id;
    
        @ManyToOne
        private Employee manager;
    
        @Column(name = "employee_name")
        private String employeeName;
    
  • @Transient
    在您的映射中是无用的,我们只在 希望使用不会在数据库中持久化的属性

  • 最重要的是,确保将类映射到
    @Entity
    ,这样它就可以 保存在数据库中

示例:


您可以检查它是否使用了您想要实现的相同模型。

您只需与Employee表有一个manytone关系,即多个员工可以拥有同一个经理(同时也是员工),对于经理,此字段将保持为空,如下所示:

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
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="manager_id")
private Employee manager;
@OneToMany(mappedBy="manager")
private Set<Employee> subordinates = new HashSet<Employee>();
@Column(name = "employee_name")
private String employeeName;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    private Employee manager;

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

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