6.1 Mélyfüggőség-kezelés
És még néhány hasznos és érdekes dolog a @OneToMany megjegyzésekkel és hasonlókkal kapcsolatban. Mindegyiknek 4 gyakran használt opciója van:
- kaszkád = CascadeType.ALL
- orphanRemoval = igaz
- fetch = FetchType.LAZY
Most részletesebben elemezzük őket. És kezdjük a legérdekesebbel - CascadeType . Ez a paraméter határozza meg, hogy mi történjen a függő entitásokkal, ha megváltoztatjuk a fő entitást.
A JPA specifikáció a következő értékeket tartalmazza ehhez a paraméterhez:
- MINDEN
- TARTOZIK
- ÖSSZEOLVAD
- ELTÁVOLÍTÁS
- FRISSÍTÉS
- LESZÁLLÍTÁS
A Hibernate azonban ezt a specifikációt további három lehetőséggel bővíti:
- MEGISMÉTELNI
- SAVE_UPDATE
- ZÁR
Természetesen erős párhuzam van az adatbázissal és a CONSTRANIS-szal. Vannak azonban eltérések is. A Hibernate megpróbálja elrejteni az adatbázissal végzett valódi munkát, amennyire csak lehetséges, így ezek a hibernált kaszkádok pontosan az entitásobjektumokról szólnak.
6.2 CascadeType
A kaszkád paraméter leírja, hogy mi történjen a függő objektumokkal, ha megváltoztatjuk a szülőt (főobjektumot). Leggyakrabban ezt a paramétert az objektumfüggőségeket leíró megjegyzésekkel együtt használják:
Példa:
OneToOne(cascade = CascadeType.ALL)
Vagy így:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
Külön megjegyzésként is írható:
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
Most beszéljünk többet arról, mit jelentenek ezek a megjegyzések.
6.3 MINDEN, MEGMARADÁS, ÖSSZESÍTÉS
CascadeType.ALL
azt jelenti, hogy a szülőobjektummal végrehajtott összes műveletet meg kell ismételni annak függő objektumainál.
CascadeType.PERSIST
azt jelenti, hogy ha a szülőobjektumot elmentjük az adatbázisba, akkor ugyanezt kell tenni a függő objektumaival is. Példa:
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.PERSIST, mappedBy="task")
private EmployeeTask task;
}
Példa az osztállyal való munkára:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
session.persist(director);
session.flush();
Csak egy Employee típusú objektumot mentünk el, a hozzá tartozó EmployeeTask objektum automatikusan mentésre kerül az adatbázisba.
CascadeType.MERGE
azt jelenti, hogy ha frissítjük a szülő objektumot az adatbázisban, akkor ugyanezt kell tenni a függő objektumaival is.
6.4 ELTÁVOLÍTÁS, TÖRLÉS, LEVÁLASZTÁS
CascadeType.REMOVE
azt jelenti, hogy ha törölünk egy szülőobjektumot az adatbázisból, akkor ugyanezt kell tenni a függő objektumaival is.
CascadeType.DELETE
ugyanazt jelenti. Ezek szinonimák. Csak más specifikációból.
CascadeType.DETACH
azt jelenti, hogy ha eltávolítjuk a szülőobjektumot a munkamenetből, akkor ugyanezt kell tenni a függő objektumaival is. Példa:
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.DETACH, mappedBy="task")
private EmployeeTask task;
}
Példa az osztállyal való munkára:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
director.task = task;
session.flush();
assertThat(session.contains(director)).isTrue();
assertThat(session.contains(task)).isTrue();
session.detach(director);
assertThat(session.contains(director)).isFalse();
assertThat(session.contains(task)).isFalse();
CascadeType.REFRESH
és CascadeType.SAVE_UPDATE
ugyanúgy működnek, ahogy várjuk – a szülőobjektummal végrehajtott műveleteket a függő objektumra duplikálják.
6.5 Árva eltávolítási lehetőség
Néha találkozhat a paraméterrel is orphan
. Ez az árva eltávolítás rövidítése. Arra szolgál, hogy ne legyenek alárendelt entitások szülő entitások nélkül.
OneToOne(orphan = true)
Ha ez a paraméter igazra van állítva, akkor az utód entitás törlődik, ha eltűntminden link. Nem pontosan ugyanaz, mint Cascade.REMOVE
.
Előfordulhat, hogy több szülőentitás hivatkozik egy gyermekre. Ekkor előnyös, ha nem törlődik a szülő entitás törlésével együtt, hanem csak akkor, ha minden hivatkozást érvénytelenítenek.
Tegyük fel, hogy van egy osztályod:
@Entity
@Table(name="user")
class Employee {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, orphan = true)
@JoinColumn(name = "employee_id")
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.tasks.get(0);
director.tasks.remove(task)
session.persist(director);
session.flush();
Az EmployeeTask objektum törlődik, mert nem maradt rá hivatkozás. Ugyanakkor senki sem törölte a szülőobjektumot.
6.6 letöltési lehetőség
A lekérés opció lehetővé teszi a függő objektumok betöltésének szabályozását. Általában két érték valamelyikét veszi igénybe:
FetchType.LAZY
FetchType.EAGER
Ez egy nagyon érdekes téma, különféle buktatókkal, ezért jobb, ha külön előadásban beszélek róla.
GO TO FULL VERSION