カスケード= {「削除」} VS orphanRemoval = true VS ondelete = "CASCADE


93

親エンティティが削除されたときに自動的に子エンティティを削除するために、以下の方法についていくつかの情報を収集しようとしました。最も一般的な方法は、cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE"の 3つのアノテーションを使用することです。

私は3番目のものについて少し混乱しています:ondelete = "CASCADE"、これに関する教義の公式ドキュメントの説明は非常に少ないため)、私が収集した以下の情報を誰かが私に確認し、私の研究から理解できれば幸いですネットと経験...

何をする

Cascade = {"remove"}
==>所有側エンティティがある場合、反対側のエンティティは削除されます。あなたが他の所有する側の実体を持つmanytomanyにいる場合でも。
-コレクションで使用する必要があります(OneToManyまたはManyToMany関係で)-ORMでの
実装

orphanRemoval = true
==>所有側エンティティがANDであり、他の所有側エンティティに接続されていない場合、反対側のエンティティは削除されます。( ref。doctrine official_doc -ORMでの実装
-OneToOne、OnetoManyまたはManyToManyで使用できます

onDelete = "CASCADE"
==>これにより、データベース内の外部キー列にOn Delete Cascadeが追加されます
-この戦略は、正しく理解するのが少し難しいですが、非常に強力で高速です。( ref。doctrine official_doc ...しかし、これ以上の説明は読んでいません)-ORM
は(以前の2つの方法と比較して)必要な作業が少ないため、パフォーマンスが向上します。

その他の情報
-これらの3つの方法はすべて双方向関係エンティティに実装されています(そうですか???)。
cascade = {"remove"}を使用すると、外部キーonDelete = CASCADEが完全にバイパスされます。(参考文献doctrine_official_doc

コードでの使用例

  • orphanRemovalおよびcascade = {"remove"}は、逆エンティティクラスで定義されています。
  • ondelete = "CASCADE"は所有者エンティティで定義されています
  • @ORM \ JoinColumn(onDelete = "CASCADE")と書いてdoctrineに列名を処理させることもできます

カスケード= {「削除」}

/**
* @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; 

1
それは良い説明を持つstackoverflow.com/questions/25515007/...
Gregsparrow

回答:


61

onDelete="CASCADE"データベース自体によって管理されます。cascade={"remove"}教義によって管理されています。

onDelete="CASCADE"doctrineではなくデータベースレベルで操作が実行されるため、より高速です。削除はDoctrineではなくデータベースサーバーによって実行されます。cascade={"remove"}教義実体そのものを管理する必要があり、それは、他の所有エンティティを持っていないかどうかを確認するために、余分なチェックを実行します。他に存在しない場合は、エンティティを削除します。ただし、これによりオーバーヘッドが生じます。


カスケード= {「削除」}

  • 所有側エンティティがある場合、反対側のエンティティは削除されます。あなたが他の所有する側の実体を持つmanytomanyにいる場合でも。いいえ、エンティティが別のものによって所有されている場合。削除されません。
  • コレクションで使用する必要があります(OneToManyまたはManyToMany関係で)
  • ORMでの実装

orphanRemoval = "true"

  • 所有側エンティティがANDであり、他の所有側エンティティに接続されていない場合、反対側のエンティティは削除されます。正確には、これにより、Doctrineは他のエンティティによって所有されていないかのように動作するため、削除されます。
  • ORMでの実装
  • OneToOne、OnetoMany、ManyToManyで使用できます

onDelete = "CASCADE"

  • これにより、データベースの外部キー列に「削除時のカスケード」が追加されます
  • この戦略を正しく行うには少し注意が必要ですが、非常に強力で高速です。(これはDoctrineの公式チュートリアルからの引用です...しかし、これ以上の説明は見ていません)
  • ORMは(以前の2つの方法と比較して)必要な作業が少ないため、パフォーマンスが向上します。

3
@ waaghals。カスケードに関するコメントについて= {"remove"} ==>エンティティArticleとCategoryの間にManyToMany関係があります。記事($ em-> remove($ article);)を削除すると、これらのカテゴリが他の記事にもリンクされている場合でも、この記事にリンクされているすべてのカテゴリが削除されます。だからあなたが書いているように振る舞わないと私は言うでしょう。
Alexis_D 2014

2
@ waaghals。orphanRemoval = "true"へのコメントについて「所有する側のエンティティがある場合、反対側のエンティティは削除され、他のエンティティによって所有されていない」という文章は、Doctrineの公式ページから引用されています。doctrine = orphanremoval
Alexis_D 2014

1
@Alexis_D、あなたのコメントに完全に同意します答えは正しくなく、初心者には本当に混乱する可能性があります
Stepan Yudin

3
私が読んだ明確な例の1つ:gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S

@VictorSのリンクは非常に明確です。私はもはやDoctrineを使用していませんので、それがどのように機能するかを直接知ることなしに私の答えを更新できないと感じます。誰かが私の答えを更新できればそれは素晴らしいでしょう。
Waaghals 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.