5.1 Iba't ibang anyo ng isa-sa-isang komunikasyon

May isa pang kawili-wili at medyo partikular na kaso ng isang relasyon sa pagitan ng dalawang klase ng Entity - isang one-to-one na relasyon.

Tinatawag ko ang kasong ito na napaka-espesipiko, dahil ito ay higit pa tungkol sa mga bagay sa Java kaysa sa isang database. Sa database, mayroon lamang dalawang pagpipilian para sa ugnayan sa pagitan ng mga talahanayan:

  • Ang hilera ng talahanayan ay naglalaman ng isang link sa id ng isa pang talahanayan.
  • Ginagamit ang talahanayan ng serbisyo para sa marami-sa-maraming relasyon.

Sa kaso ng mga klase ng Entity, maaaring may mga opsyon na inilalarawan ng ilang anotasyon:

  • @Naka-embed
  • One-sided OneToOne
  • Bilateral OneToOne
  • @MapsId

Sa ibaba ay isasaalang-alang natin ang pinakasikat sa kanila.

5.2 Naka-embed

Siyanga pala, napag-isipan na namin ang pinakasimpleng opsyon sa isa-sa-isang@Embedded komunikasyon - ito ay isang anotasyon . Sa kasong ito, mayroon kaming dalawang klase na nakaimbak sa parehong talahanayan sa database.

Sabihin nating gusto naming iimbak ang address ng user sa klase ng 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;
}

Pagkatapos ay kailangan lang nating magdagdag ng field na may ganitong address sa klase ng User :


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

Gagawin ng hibernate ang natitira: ang data ay maiimbak sa isang talahanayan, ngunit kapag nagsusulat ng mga query sa HQL, kakailanganin mong gumana sa mga field ng klase.

Halimbawa ng query ng HQL:

select from User where address.city = 'Paris'

5.3 One-sided OneToOne

Isipin ngayon ang sitwasyon: mayroon kaming source table na empleyado at isang gawain na tumutukoy sa empleyado. Ngunit alam naming sigurado na ang maximum na isang gawain ay maaaring italaga sa isang user. Pagkatapos ay magagamit natin ang anotasyon upang ilarawan ang sitwasyong ito @OneToOne.

Halimbawa:


@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;
}

Sisiguraduhin ng hibernate na hindi lamang isang gawain ang may isang user, ngunit ang isang user ay mayroon lamang isang gawain. Kung hindi, ang kasong ito ay halos hindi naiiba sa @ManyToOne.

5.4 Bilateral OneToOne

Ang nakaraang pagpipilian ay maaaring maging isang maliit na abala, dahil madalas na nais mong magtalaga ng isang empleyado hindi lamang sa isang gawain, ngunit din magtalaga ng isang gawain sa isang empleyado.

Upang gawin ito, maaari mong idagdag ang field ng EmployeeTask sa klase ng Employee at bigyan ito ng mga tamang anotasyon.


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

Mahalaga!Ang talahanayan ng empleyado ay walang task_id field , sa halip ang employee_id field ng task table ay ginagamit upang magtatag ng relasyon sa pagitan ng mga talahanayan .

Ang pagtatatag ng koneksyon sa pagitan ng mga bagay ay ganito ang hitsura:


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();

Upang alisin ang link, dapat ding alisin ang mga link mula sa parehong mga bagay:


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();