Hibernate @OneToMany注释究竟是如何工作的?

时间:2015-07-10 10:18:19

标签: java hibernate orm one-to-many hibernate-mapping

我对Hibernate很新,我正在研究它。我在理解 OneToMany 注释的工作原理时遇到了一些问题。

所以我有这两个实体类:代表学生的学生和代表指导学生的人的指南。因此,每个学生都与一个指南相关联,但是单个指南可以跟随更多的学生。我想要一个指南来了解与他有关的学生。

所以我有:

学生

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="enrollment_id", nullable=false)
    private String enrollmentId;    

    private String name;

    @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
    @JoinColumn(name="guide_id")
    private Guide guide;

    public Student() {}
    public Student(String enrollmentId, String name, Guide guide) {
        this.enrollmentId = enrollmentId;
        this.name = name;
        this.guide = guide;
    }

    public Guide getGuide() {
        return guide;
    }
    public void setGuide(Guide guide) {
        this.guide = guide;
    }

}

指南字段中的 @ManyToOne 注释:

@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="guide_id")
private Guide guide; 

表示单个指南与单个学生相关联,但指南可以跟随许多学生。这样对吗?指定的级联设置究竟是做什么的?我认为这意味着当我将包含指南对象的Student对象保留为字段时,此指南对象也会自动保留。当我删除学生对象时,同样的事情就会发生,相关的指南记录会被删除...但我并不完全确定...

好的,这样做我会在学生表中的记录与指南中的记录之间建立单向关系table因为在学生表中我会有一个外键加入指南表,所以学生可以知道它的指南,但这样做,指南无法知道跟着学生......这不聪明。

为此,指南类以这种方式实现:

@Entity
public class Guide {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="staff_id", nullable=false)
    private String staffId; 

    private String name;
    private Integer salary;

    @OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
    private Set<Student> students = new HashSet<Student>(); 

    public Guide() {}
    public Guide(String staffId, String name, Integer salary) {
        this.staffId = staffId;
        this.name = name;
        this.salary = salary;
    }

    public Set<Student> getStudents() {
        return students;
    }   
    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    public void addStudent(Student student) {
        students.add(student);
        student.setGuide(this);
    }

}   

所以,正如你所看到的,这个类包含:

@OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>(); 

它用于声明双向关系。

因此在我看来,此注释会自动在学生表中创建一个 guide_id 字段,表示实现双向的外键关系。

实际上使用此映射,学生表会以这种方式在我的数据库中自动创建:

'id', 'bigint(20)', 'NO', 'PRI', NULL, 'auto_increment'
'enrollment_id', 'varchar(255)', 'NO', '', NULL, ''
'name', 'varchar(255)', 'YES', '', NULL, ''
'guide_id', 'bigint(20)', 'YES', 'MUL', NULL, ''

因此,在学生实体课程中,我没有定义 guide_id 字段,但我在数据库的学生表中有。所以我认为表中该字段的创建取决于指南实体类中定义的先前 @OneToMany 注释。这是正确的还是我错过了什么?

1 个答案:

答案 0 :(得分:3)

是的,您可以在没有双向关联的情况下定义@OneToMany实体,并且添加的列位于数据库中的Many实体端(即使实体不知道它已链接到One - 侧实体)。

您也可以使用连接表,但这不是必需的。