5.1 Diverse vormen van één-op-één communicatie

Er is nog een interessant en nogal specifiek geval van een relatie tussen twee Entiteitsklassen - een een-op-een relatie.

Ik noem dit geval heel specifiek, omdat het meer om Java-objecten gaat dan om een ​​database. In de database zijn er slechts twee opties voor de relatie tussen tabellen:

  • De tabelrij bevat een link naar de id van een andere tabel.
  • De servicetabel wordt gebruikt voor veel-op-veel-relaties.

In het geval van Entity-klassen kunnen er opties zijn die door verschillende annotaties worden beschreven:

  • @Ingebed
  • Eenzijdig OneToOne
  • Bilaterale OneToOne
  • @MapsId

Hieronder zullen we de meest populaire bekijken.

5.2 Ingebed

Overigens hebben we de eenvoudigste optie voor één-op-één-@Embedded communicatie al overwogen - dit is een annotatie . In dit geval hebben we twee klassen opgeslagen in dezelfde tabel in de database.

Laten we zeggen dat we het adres van de gebruiker willen opslaan in de klasse 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;
}

Dan hoeven we alleen maar een veld met dit adres toe te voegen aan de User- klasse :


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

Hibernate doet de rest: de gegevens worden in één tabel opgeslagen, maar bij het schrijven van HQL-query's moet u op klassenvelden werken.

Voorbeeld van HQL-query:

select from User where address.city = 'Paris'

5.3 Eenzijdig OneToOne

Stel je nu de situatie voor: we hebben een brontabelmedewerker en een taak die verwijst naar medewerker. Maar we weten zeker dat er maximaal één taak aan één gebruiker kan worden toegewezen. Dan kunnen we de annotatie gebruiken om deze situatie te beschrijven @OneToOne.

Voorbeeld:


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

Hibernate zorgt ervoor dat niet alleen één taak één gebruiker heeft, maar ook dat één gebruiker slechts één taak heeft. Anders verschilt deze zaak praktisch niet van @ManyToOne.

5.4 Bilaterale OneToOne

De vorige optie kan een beetje onhandig zijn, omdat je een medewerker vaak niet alleen aan een taak wilt toewijzen, maar ook een taak aan een medewerker wilt toewijzen.

Om dit te doen, kunt u het veld EmployeeTask toevoegen aan de klasse Employee en deze de juiste annotaties geven.


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

Belangrijk!De werknemerstabel heeft geen taak_id- veld , in plaats daarvan wordt het werknemer_id- veld van de takentabel gebruikt om een ​​relatie tussen tabellen tot stand te brengen .

Het tot stand brengen van een verbinding tussen objecten ziet er als volgt uit:


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

Om de koppeling te verwijderen, moeten de koppelingen ook van beide objecten worden verwijderd:


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