5.1 A személyes kommunikáció különféle formái

Van egy másik érdekes és meglehetősen sajátos esete a két entitásosztály közötti kapcsolatnak – egy egy-egy kapcsolat.

Ezt az esetet nagyon specifikusnak nevezem, mivel inkább Java objektumokról van szó, mint adatbázisról. Az adatbázisban csak két lehetőség van a táblák közötti kapcsolatra:

  • A táblázat sora egy másik tábla azonosítójára mutató hivatkozást tartalmaz.
  • A szerviztábla a sok-sok kapcsolatokhoz használatos.

Az entitásosztályok esetében lehetnek olyan opciók, amelyeket több megjegyzés ír le:

  • @Beágyazott
  • Egyoldalú OneToOne
  • Kétoldalú OneToOne
  • @MapsId

Az alábbiakban megvizsgáljuk közülük a legnépszerűbbeket.

5.2 Beágyazott

Mellesleg, már megvizsgáltuk a legegyszerűbb egy-egy@Embedded kommunikációs lehetőséget - ez egy megjegyzés . Ebben az esetben két osztályt tárolunk ugyanabban a táblában az adatbázisban.

Tegyük fel, hogy a felhasználó címét a UserAddress osztályban szeretnénk tárolni :


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

Ezután csak hozzá kell adnunk egy mezőt ezzel a címmel a User osztályhoz :


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

A többit a Hibernate elvégzi: az adatok egy táblában tárolódnak, de HQL lekérdezések írásakor osztálymezőkkel kell operálni.

Példa a HQL lekérdezésre:

select from User where address.city = 'Paris'

5.3 Egyoldalas OneToOne

Képzelje el most a helyzetet: van egy forrástábla alkalmazottunk és egy feladatunk, amely az alkalmazottra vonatkozik. Azt viszont biztosan tudjuk, hogy egy felhasználóhoz maximum egy feladat rendelhető. Ezután az annotációval leírhatjuk ezt a helyzetet @OneToOne.

Példa:


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

A hibernálás gondoskodik arról, hogy ne csak egy feladathoz legyen egy felhasználó, hanem azt is, hogy egy felhasználónak csak egy feladata legyen. Egyébként ez az eset gyakorlatilag nem különbözik a -tól @ManyToOne.

5.4 Kétoldalú OneToOne

Az előző lehetőség kicsit kényelmetlen lehet, mert gyakran nem csak egy feladathoz akarunk egy munkatársat kijelölni, hanem egy munkatárshoz is szeretnénk feladatot rendelni.

Ehhez hozzáadhatja az EmployeeTask mezőt az Employee osztályhoz, és megadhatja a megfelelő megjegyzéseket.


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

Fontos!Az alkalmazotti tábla nem rendelkezik feladat_id mezővel , helyette a feladattábla munkavállaló_id mezője a táblák közötti kapcsolat létrehozására szolgál .

Az objektumok közötti kapcsolat létrehozása így néz ki:


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

A hivatkozás eltávolításához a hivatkozásokat mindkét objektumról is el kell távolítani:


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