cascade = {“remove”} VS orphanRemoval = true VS ondelete = "CASCADE

94

Saya mencoba mengumpulkan beberapa informasi tentang cara berikut untuk menghapus entitas anak secara otomatis ketika entitas induk dihapus. Tampaknya cara yang paling umum adalah menggunakan salah satu dari tiga anotasi tersebut: cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE" .

Saya agak bingung tentang yang ketiga: ondelete = "CASCADE" , karena penjelasan dalam dokumentasi resmi doktrin tentang yang satu ini sangat langka) dan saya akan sangat senang jika seseorang dapat mengkonfirmasi kepada saya informasi berikut yang saya kumpulkan dan pahami dari penelitian saya tentang bersih dan pengalaman ...

APA YANG DILAKUKANNYA

cascade = {"remove"}
==> entitas di sisi terbalik dihapus ketika entitas sisi yang memiliki adalah. Bahkan jika Anda berada di banyak orang dengan entitas sisi lain yang memiliki.
- harus digunakan pada pengumpulan (jadi dalam hubungan OneToMany atau ManyToMany)
- implementasi di ORM

orphanRemoval = true
==> entitas di sisi terbalik dihapus ketika entitas sisi pemilik adalah DAN tidak lagi terhubung ke entitas sisi pemilik lainnya. (ref. doktrin official_doc - implementasi di ORM
- dapat digunakan dengan OneToOne, OnetoMany atau ManyToMany

onDelete = "CASCADE"
==> ini akan menambahkan On Delete Cascade ke kolom kunci asing dalam database
- Strategi ini agak sulit dilakukan tetapi bisa sangat kuat dan cepat. (ref. doktrin official_doc ... tetapi belum membaca lebih banyak penjelasan)
- ORM harus melakukan lebih sedikit pekerjaan (dibandingkan dengan dua cara melakukan sebelumnya) dan oleh karena itu harus memiliki kinerja yang lebih baik.

informasi lain
- semua 3 cara melakukannya diimplementasikan pada entitas hubungan dua arah ( benar ??? )
- menggunakan cascade = {"remove"} sepenuhnya melewati kunci asing apa pun onDelete = CASCADE. (ref. doktrin_official_doc )

CONTOH CARA MENGGUNAKANNYA DALAM KODE

  • orphanRemoval dan cascade = {"remove"} ditentukan dalam kelas entitas terbalik.
  • ondelete = "CASCADE" didefinisikan dalam entitas pemilik
  • Anda juga dapat menulis @ORM \ JoinColumn (onDelete = "CASCADE") dan biarkan doktrin menangani nama kolom

cascade = {"remove"}

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers

orphanRemoval = true

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers

onDelete = "CASCADE"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 
Alexis_D
sumber
1
itu memiliki penjelasan yang baik stackoverflow.com/questions/25515007/…
Gregsparrow

Jawaban:

63

onDelete="CASCADE"dikelola oleh database itu sendiri. cascade={"remove"}dikelola oleh doktrin.

onDelete="CASCADE"lebih cepat karena operasi dilakukan pada tingkat database, bukan berdasarkan doktrin. Penghapusan dilakukan oleh server database dan bukan Doktrin. Dengan cascade={"remove"}doktrin harus mengelola entitas itu sendiri dan akan melakukan pemeriksaan ekstra untuk melihat apakah ia tidak memiliki entitas pemilik lainnya. Jika tidak ada yang lain, entitas tersebut akan dihapus. Tapi ini menciptakan overhead.


cascade = {"remove"}

  • entitas di sisi terbalik dihapus ketika entitas sisi yang memiliki adalah. Bahkan jika Anda berada di banyak orang dengan entitas sisi lain yang memiliki. Tidak, jika entitas dimiliki oleh sesuatu yang lain. Ini tidak akan dihapus.
  • harus digunakan pada koleksi (jadi dalam hubungan OneToMany atau ManyToMany)
  • implementasi di ORM

orphanRemoval = "true"

  • entitas di sisi terbalik dihapus jika entitas sisi pemilik adalah DAN tidak lagi terhubung ke entitas sisi pemilik lainnya. Tidak persis, hal ini membuat doktrin berperilaku seolah-olah tidak dimiliki oleh entitas lain, dan dengan demikian menghapusnya.
  • implementasi di ORM
  • dapat digunakan dengan OneToOne, OnetoMany atau ManyToMany

onDelete = "CASCADE"

  • ini akan menambahkan On Delete Cascade ke kolom foreign key IN THE DATABASE
  • Strategi ini agak sulit dilakukan dengan benar, tetapi bisa sangat kuat dan cepat. (ini adalah kutipan dari tutorial resmi doktrin ... tetapi belum melihat lebih banyak penjelasan)
  • ORM harus melakukan lebih sedikit pekerjaan (dibandingkan dengan dua cara sebelumnya) dan karena itu harus memiliki kinerja yang lebih baik.
Waaghals
sumber
3
@ waagh. Tentang komentar Anda di cascade = {"remove"} ==> Saya memiliki hubungan ManyToMany antara Entitas Artikel dan Kategori. Ketika saya menghapus sebuah Artikel ($ em-> remove ($ article);) itu menghapus semua kategori yang ditautkan ke artikel ini BAHKAN jika kategori itu juga ditautkan ke artikel lain. jadi saya akan mengatakan bahwa itu tidak berperilaku seperti yang Anda tulis.
Alexis_D
2
@ waagh. Tentang komentar Anda di orphanRemoval = "true" Kalimat yang saya tulis "entitas di sisi terbalik dihapus ketika entitas sisi yang memiliki adalah, dan tidak dimiliki oleh entitas lain mana pun" dikutip dari halaman resmi doktrin. doktrin = yatim piatu .
Alexis_D
1
@Alexis_D, setuju sepenuhnya dengan komentar Anda Jawabannya salah dan bisa sangat membingungkan bagi pemula
Stepan Yudin
3
Salah satu contoh yang lebih jelas yang pernah saya baca: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S
Tautan @VictorS sangat jelas. Saya tidak lagi bekerja dengan Doktrin jadi merasa saya tidak dapat memperbarui jawaban saya tanpa mengetahui secara langsung cara kerjanya. Jika seseorang dapat memperbarui jawaban saya, itu akan sangat bagus.
Waaghals