6.1 Malalim na pamamahala sa dependency

At ilang mas kapaki-pakinabang at kawili-wiling mga bagay tungkol sa @OneToMany annotation at mga katulad nito. Lahat sila ay may 4 na karaniwang ginagamit na opsyon:

  • cascade = CascadeType.ALL
  • orphanRemoval = totoo
  • fetch = FetchType.LAZY

Ngayon ay susuriin namin ang mga ito nang mas detalyado. At magsisimula tayo sa pinakakawili-wili - CascadeType . Tinutukoy ng parameter na ito kung ano ang dapat mangyari sa mga umaasang entity kung babaguhin natin ang pangunahing entity.

Ang detalye ng JPA ay may mga sumusunod na halaga para sa parameter na ito:

  • LAHAT
  • MAGPUMILIT
  • PAGSASAMA
  • TANGGALIN
  • REFRESH
  • I-DETACH

Gayunpaman, pinalawak ng Hibernate ang detalyeng ito sa tatlong higit pang mga opsyon:

  • GUMULI
  • SAVE_UPDATE
  • LOCK

Mayroong, siyempre, isang malakas na parallel sa database at sa kanilang CONSTRANIS. Gayunpaman, mayroon ding mga pagkakaiba. Sinusubukan ng Hibernate na itago ang totoong trabaho sa database hangga't maaari, kaya ang mga Hibernate Cascade na ito ay eksaktong tungkol sa mga bagay na Entity.

6.2 Uri ng Cascade

Inilalarawan ng cascade parameter kung ano ang dapat mangyari sa mga umaasa na bagay kung babaguhin natin ang kanilang magulang (master object). Kadalasan, ginagamit ang parameter na ito kasama ng mga anotasyon na naglalarawan sa mga dependency ng object:

Halimbawa:

OneToOne(cascade = CascadeType.ALL)

O tulad nito:

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})

Maaari rin itong isulat bilang isang hiwalay na anotasyon:

@Cascade({ org.hibernate.annotations.CascadeType.ALL })

Ngayon, pag-usapan natin ang higit pa tungkol sa kung ano ang ibig sabihin ng mga anotasyong ito.

6.3 LAHAT, MAGPAPATAY, MAGSAMA

CascadeType.ALLnangangahulugan na ang lahat ng mga aksyon na ginagawa namin sa parent object ay dapat na ulitin para sa mga umaasa nitong object.

CascadeType.PERSISTNangangahulugan na kung i-save natin ang object ng magulang sa database, dapat itong gawin sa mga umaasa na bagay nito. Halimbawa:


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

Isang halimbawa ng pagtatrabaho sa klase na ito:


Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
 
session.persist(director);
session.flush();

Nagse-save lamang kami ng isang object ng uri ng Empleyado, ang nakadepende nitong object na EmployeeTask ay awtomatikong mase-save sa database.

CascadeType.MERGEnangangahulugan na kung i-update natin ang parent object sa database, dapat itong gawin sa mga umaasa nitong object.

6.4 TANGGALIN, TANGGALIN, TANGGAL

CascadeType.REMOVEnangangahulugan na kung tatanggalin natin ang isang parent object sa database, dapat itong gawin sa mga umaasa nitong object.

CascadeType.DELETEpareho ang ibig sabihin. Ito ay mga kasingkahulugan. Lamang mula sa iba't ibang mga pagtutukoy.

CascadeType.DETACHnangangahulugan na kung aalisin natin ang parent object mula sa session, dapat itong gawin sa mga umaasa nitong object. Halimbawa:


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

Isang halimbawa ng pagtatrabaho sa klase na ito:


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.REFRESHat CascadeType.SAVE_UPDATEgumagana sa parehong paraan tulad ng inaasahan namin - kino-duplicate nila ang mga aksyon na ginagawa kasama ang parent object sa umaasa nitong object.

6.5 Opsyon sa pag-alis ng ulila

Minsan din ay maaari mong makita ang parameter orphan. Ito ay maikli para sa Orphan removal. Ginagamit ito upang matiyak na walang child entity na walang parent entity.

OneToOne(orphan = true)

Kung nakatakda ang parameter na ito sa true, made-delete ang child entity kung nawala itolahat ng link. Hindi ito eksaktong kapareho ng Cascade.REMOVE.

Maaaring mayroon kang isang sitwasyon kung saan ang ilang entity ng magulang ay tumutukoy sa isang bata. Pagkatapos ay kapaki-pakinabang na hindi ito tinanggal kasama ng pagtanggal ng parent entity, ngunit kung ang lahat ng mga reference dito ay mapawalang-bisa.

Sabihin nating may klase ka:


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

Ang EmployeeTask object ay tatanggalin dahil walang mga reference na natitira dito. Kasabay nito, walang nagtanggal ng parent object.

6.6 opsyon sa pagkuha

Binibigyang-daan ka ng opsyon sa pagkuha na kontrolin kung paano nilo-load ang mga umaasang bagay. Karaniwang tumatagal ng isa sa dalawang halaga:

  • FetchType.LAZY
  • FetchType.EAGER

Ito ay isang napaka-kagiliw-giliw na paksa na may iba't ibang mga pitfalls, kaya mas mabuting pag-usapan ko ito sa isang hiwalay na lecture.