1. ホーム
  2. php

ドクトリン・カスケード・オペレーションを理解する

2023-08-28 04:35:59

質問

Doctrine のアソシエーションに対するカスケード操作について理解度を確認したいです。この質問のために、私は2つのモデルを持っています。 CustomerInsuree .

を多対多の関係で定義した場合。 CustomerInsuree と設定し cascade{"all"} になることは理解しています。

  • 顧客に新しい保険加入者を追加すると、この保険加入者が永続化され、結合テーブルに関連付けが作成されます。
  • コレクションからインシュレーを削除すると、インシュレーが顧客から切り離され、顧客がインシュレーから切り離されます。
  • 顧客を削除すると、その顧客に関連するすべての被保険者が削除されます。

の関連付けの定義です。 Customers .

/**
 * @ORM\ManyToMany(targetEntity="Insuree", inversedBy="customers", cascade={"all"})
 * @ORM\JoinTable(name="customer_insuree",
 *      joinColumns={@ORM\JoinColumn(name="customer_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="insuree_id", referencedColumnName="id")}
 * )
 */
protected $insurees;

の間に逆多対多の関係を定義すると、その関係から InsureeCustomer と設定し cascade{"all"} になることは理解しています。

  • insuree に新しい顧客を追加すると、この顧客が永続化され、結合テーブルに関連付けが作成されます。
  • コレクションから顧客を削除すると、その顧客がインシュレーから切り離され、インシュレーが顧客から切り離されます。
  • insureeを削除すると、それに関連するすべてのカスタマーが削除されます。

の関連付けの定義です。 Insurees .

/**
 * @ORM\ManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"all"})
 */
protected $customers;

保険加入者を削除しても、関連する顧客はすべて削除されず、保険加入者とその顧客との関連付けが削除されるだけですか?

/**
 * @ORM\ManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"persist", "merge", "detach"})
 */
protected $customers;

どのように解決するのですか?

削除する

については正しいです。 cascade={"persist"} は、エンティティ A を永続化すると、Doctrine はコレクション内のすべての B のエンティティも永続化することを意味します。

についても正しいです。 cascade={"remove"} は、エンティティ A を削除すると、Doctrine はコレクション内のすべての B のエンティティも削除することを意味します。

なぜなら、エンティティ A を削除すると、B のエンティティにもこの操作が及ぶため、B のエンティティは他の A のエンティティに関連している可能性があるからです。

デタッチ & マージ

あなたは ではない について正しく cascade={"detach"}cascade={"merge"} :

コレクションへのエンティティの追加・削除は、何かというと あなた を行う必要があります (あなたのコードで)。それについて読む はこちら .

切り離し は、エンティティをEntityManagerから切り離すことを意味します。EntityManager はもはやそのエンティティを管理しません。これにより、デタッチされたエンティティは、それがすでにデータベースにある(しかしEntityManagerにそれを意識させないようにした)ことを除けば、新しくインスタンス化されたエンティティと同じになります。

言い換えれば cascade={"detach"} は、エンティティ A をデタッチすると、Doctrine はコレクション内のすべての B のエンティティもデタッチすることを意味します。

マージ の逆で デタッチ : デタッチされたエンティティをEntityManagerにマージして戻すことになります。

注意点としては merge() は実際には 新しい を返しますが、渡されたデタッチドオブジェクトはアンマネージドなままです。