5.1 Berbagai bentuk komunikasi satu-ke-satu

Ada kasus lain yang menarik dan agak spesifik tentang hubungan antara dua kelas Entitas - hubungan satu-ke-satu.

Saya menyebut kasus ini sangat spesifik, karena ini lebih tentang objek Java daripada database. Dalam database, hanya ada dua opsi untuk hubungan antar tabel:

  • Baris tabel berisi tautan ke id tabel lain.
  • Tabel layanan digunakan untuk hubungan banyak-ke-banyak.

Dalam kasus kelas Entitas, mungkin ada opsi yang dijelaskan oleh beberapa anotasi:

  • @ Tertanam
  • OneToOne satu sisi
  • Bilateral One To One
  • @MapsId

Di bawah ini kami akan mempertimbangkan yang paling populer di antara mereka.

5.2 Tertanam

Omong-omong, kami telah mempertimbangkan opsi komunikasi satu-ke-satu yang paling sederhana - ini adalah anotasi @Embedded. Dalam hal ini, kami memiliki dua kelas yang disimpan dalam tabel yang sama di database.

Katakanlah kita ingin menyimpan alamat pengguna di kelas UserAddress :


@Embeddable
class UserAddress {
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
}

Kemudian kita hanya perlu menambahkan field dengan alamat ini ke kelas User :


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

Hibernasi akan melakukan sisanya: data akan disimpan dalam satu tabel, tetapi saat menulis kueri HQL, Anda perlu mengoperasikan bidang kelas.

Contoh kueri HQL:

select from User where address.city = 'Paris'

5.3 Satu-sisi OneToOne

Bayangkan sekarang situasinya: kita memiliki tabel sumber karyawan dan tugas yang mengacu pada karyawan. Namun kami tahu pasti bahwa maksimal satu tugas dapat diberikan kepada satu pengguna. Kemudian kita dapat menggunakan anotasi untuk menggambarkan situasi ini @OneToOne.

Contoh:


@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;
 
   @Column(name="name")
   public String description;
 
   @OneToOne
   @JoinColumn(name = "employee_id")
   public Employee employee;
 
   @Column(name="deadline")
   public Date deadline;
}

Hibernasi akan memastikan bahwa tidak hanya satu tugas yang memiliki satu pengguna, tetapi juga satu pengguna hanya memiliki satu tugas. Kalau tidak, kasus ini praktis tidak berbeda dengan @ManyToOne.

5.4 Bilateral Satu Ke Satu

Opsi sebelumnya bisa sedikit merepotkan, karena sering kali Anda ingin menugaskan karyawan tidak hanya untuk suatu tugas, tetapi juga menugaskan tugas kepada seorang karyawan.

Untuk melakukannya, Anda dapat menambahkan bidang EmployeeTask ke kelas Employee dan memberinya anotasi yang benar.


@Entity
@Table(name="employee")
class Employee {
   @Column(name="id")
   public Integer id;
 
   @OneToOne(cascade = CascadeType.ALL, mappedBy="employee")
   private EmployeeTask task;
}

Penting!Tabel karyawan tidak memiliki bidang task_id , sebaliknya bidang employee_id dari tabel tugas digunakan untuk membuat hubungan antar tabel .

Membuat koneksi antar objek terlihat seperti ini:


Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employee = director;
director.task = task;
 
session.update(task);
session.flush();

Untuk menghapus tautan, tautan juga harus dihapus dari kedua objek:


Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.task;
 
task.employee = null;
session.update(task);
 
director.task = null;
session.update(director);
 
session.flush();