Я новичок в Hibernate и изучаю его в учебнике. У меня есть некоторые проблемы с пониманием того, как именно работает аннотация OneToMany.
Итак, у меня есть два класса сущностей: Student, который представляет студента, и Guide, который представляет человека, который направляет студента. Таким образом, каждый студент связан с одним гидом, но один гид может следовать за более чем одним студентом. Я хочу, чтобы руководство знало студентов, связанных с ним.
Так что я:
Студент:
@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, который содержит объект Guide в качестве поля, этот объект Guide также автоматически сохраняется. И то же самое происходит, когда я удаляю объект Студент, соответствующая запись Руководство удаляется... но я не совсем в этом уверен...
Хорошо, если я сделаю это таким образом, у меня будет однонаправленная связь между записью в таблице Student и записью в таблице Guide, потому что в таблица Student. У меня будет внешний ключ для присоединения к таблице Guide, чтобы учащийся мог знать своего путеводителя, но, делая это таким образом, путеводитель не может знать следующего учащегося ...и это не умно.
Для этого класс Guide реализован следующим образом:
@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 в таблице Student, которое представляет внешний ключ, реализующий двунаправленное отношение.
На самом деле, используя это сопоставление, таблица Student автоматически создается в моей базе данных следующим образом:
'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, ''
Поэтому в классе сущностей Student я не определил поле guide_id, но оно есть в таблице Student в базе данных. Поэтому я думаю, что создание этого поля в таблице зависит от предыдущей аннотации @OneToMany, определенной в классе сущности Guide. Это правильно или я что-то упускаю?