-->

Hibernate. Отношения ManyToOne (OneToMany) Unidirectional и Bidirectional

Отношения между Java-объектами и таблицами базы данных Один-ко-многим.

Существует три вида отношений между таблицами реляционных баз данных:
  • One-to-One,
  • One-to-Many / Many-to-One,
  • Many-to-Many.

Отношения Один-ко-многим - наиболее распространенный вид отношений .
Практическим примером таких отношений могут служить такие пары сущностей, как
  • Наниматель (один) - Работник (много);
  • Покупатель (один) - Товар (много);
  • Курс (один) - Студент (много);
  • Адрес (один) - Студент (много), т.е. по одному адресу могу проживать не менее одного студента, а каждый студент имеет только один адрес проживания:
или в виде таблиц БД:
Такого рода отношения в Hibernate обозначаются аннотациями @ManyToOne или @OneToMany, в зависимости от Java-класса, описывающего сущность, в котором они применяются.

Помимо этого, все отношения в Hibernate могут быть однонаправленными (Unidirectional) и двунаправленными (Bidirectional).

Посмотрим на примере.
Создадим два Java-класса, которые объявим сущностями Hibernate с помощью аннотации @Entity. А также поля, используемые для идентификации этих сущностей, и сопоставленные со столбцами соответствующих таблиц при помощи аннотаций @Id и @GeneratedValue.

Кроме того, в классе Student объявлена переменная address класса Address.

Address.java

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Address {  

  8.     private Long id;  
  9.     private String address;  
  10.       
  11.     @Id  
  12.     @GeneratedValue(strategy=GenerationType.AUTO)  
  13.     public Long getId() {  
  14.         return id;  
  15.     }  

  16.     public void setId(Long id) {  
  17.         this.id = id;  
  18.     }  

  19.     public String getAddress() {  
  20.         return address;  
  21.     }  

  22.     public void setAddress(String address) {  
  23.         this.address = address;  
  24.     }  
  25. }  

Student.java

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Student {  

  8.     private Long id;  
  9.     private String studentName;  
  10.     private Address address;  
  11.       
  12.     @Id  
  13.     @GeneratedValue(strategy=GenerationType.AUTO)  
  14.     public Long getId() {  
  15.         return id;  
  16.     }  

  17.     public void setId(Long id) {  
  18.         this.id = id;  
  19.     }  

  20.     public String getStudentName() {  
  21.         return studentName;  
  22.     }  

  23.     public void setStudentName(String studentName) {  
  24.         this.studentName = studentName;  
  25.     }  
  26.       
  27.     public Address getAddress() {  
  28.         return address;  
  29.     }  

  30.     public void setAddress(Address address) {  
  31.         this.address = address;  
  32.     }  
  33. }  

При создании экземпляров данных классов, в объектах класса Student можно получить его адрес проживания из переменной address класса Address.
Но из экземпляра класса Address невозможно получить данные о студентах, проживающих по адресу, связанному с данным экземпляром класса.

Данная связь называется однонаправленной (Unidirectional).

Для дальнейшего понимания отношений определим концепцию Родительской (Parent) и Дочерней (Child) таблиц.

В случае отношения Один-ко-Многим, дочерней называется таблица, содержащая внешний ключ.
В данном примере это таблица студентов, а внешний ключ - ссылка на таблицу адресов.
Проще говоря, дочерней таблицей при отношении Один-ко-Многим, является таблица, отражающая сущности "Многих"
Для реализации однонаправленной (Unidirectional) связи Один-ко-Многим достаточно использования аннотации @ManyToOne в объекте, соответствующему дочерней таблице в БД.
В нашем примере, в классе Student:

  1.     @ManyToOne
  2.     public Address getAddress() {  
  3.         return address;  
  4.     }  

Использование данной аннотации необходимо для создания Hibernate необходимого внешнего ключа в дочерней таблице Student.

Дополнительно эта аннотация может содержать параметры, описывающий поведение БД при удалении и/или вставке значений в связанные поля, например:


  1.     @ManyToOne(cascade = CascadeType.ALL)
  2.     public Address getAddress() {  
  3.         return address;  
  4.     }  




Если прикладная реализация требует получения не только адреса проживания каждого студента, но и всех студентов, проживающих по определенному адресу, то используется двунаправленная связь.

Для обозначения двунаправленной (Bidirectional) связи в Hibernate определена вторая аннотация: @OneToMany, в дополнение к аннотации @ManyToOne.

При отношении Один-ко-Многим для объекта, соответствующего дочерней таблице БД (со стороны "Многие"), используется аннотация @ManyToOne для соответствующего геттера.
А для объекта, соответствующего родительской таблице БД (со стороны "Один"), - аннотация @OneToMany для соответствующего геттера.
Для запоминания: на стороне "Многие" аннотация @ManyToOne,
а на стороне "Один" - @OneToMany
В случае двунаправленной (Bidirectional) связи необходимо дополнительно создать переменную родительского класса, которая позволит хранить коллекцию объектов дочернего класса. А так же связать геттер этой переменной с переменной дочернего класса, хранящую родительский объект, при помощью аннотации @OneToMany(mappedBy="address").
(где "address" - это имя переменной дочернего класса, отмеченная аннотацией @ManyToOne в данной связи)

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Address {  

  8.     private Long id;  
  9.     private String address;  

  10.     private Set<Student> studentSet;  
  11.       
  12.     @Id  
  13.     @GeneratedValue(strategy=GenerationType.AUTO)  
  14.     public Long getId() {  
  15.         return id;  
  16.     }  

  17.     public void setId(Long id) {  
  18.         this.id = id;  
  19.     }  

  20.     public String getAddress() {  
  21.         return address;  
  22.     }  

  23.     public void setAddress(String address) {  
  24.         this.address = address;  
  25.     }  
  26.       
  27.     @OneToMany(cascade=CascadeType.ALL, mappedBy="address" 
  28.     public Set<Student> getStudentSet()  
  29.         return studentSet;  
  30.      

  31.     public void setStudentSet(Set<Student> studentSet) {  
  32.         this.studentSet = studentSet;  
  33.     }  
  34. }  

Комментариев нет :

Отправить комментарий