web-dev-qa-db-ja.com

Doctrineカスケード操作を理解する

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"}、これは次のことを理解しています。

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

これは、Insureesの関連付けの定義です。

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

その後、カスケード、持続、マージ、デタッチに関する関係を定義すると、保険者を削除しても関連するすべての顧客は削除されません-保険者とその顧客の間の関連付けのみが削除されますか?

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

persist&remove

_cascade={"persist"}_については正しいです。つまり、エンティティAを保持すると、Doctrineはコレクション内のすべてのBエンティティも保持します。

_cascade={"remove"}_についても正しいです。つまり、エンティティAを削除すると、Doctrineはコレクション内のすべてのBエンティティも削除します。
ただし、この操作をすべてのBエンティティにカスケードするエンティティAを削除すると、それらのBエンティティが他のAエンティティに関連付けられる可能性があるため、ManyToManyアソシエーションでこれを使用したいとは思わないでしょう。

デタッチとマージ

あなたはnot _cascade={"detach"}_および_cascade={"merge"}_について正しい:

コレクションにエンティティを追加/削除することは、何かですyoする必要があります(コードで)。それについて読む こちら

Detachは、EntityManagerからエンティティを切り離すことを意味します。 EntityManagerはそのエンティティを管理しなくなります。これにより、デタッチされたエンティティは、既にデータベースに存在していることを除いて、新しくインスタンス化されたエンティティと同じになります(ただし、EntityManagerには認識させません)。

つまり、_cascade={"detach"}_は、エンティティAをデタッチすると、Doctrineはコレクション内のすべてのBエンティティもデタッチします。

Mergedetachの反対です:切り離されたエンティティをEntityManagerにマージして戻します。
merge()は実際にnew管理対象オブジェクトを返すことに注意してください。渡された分離オブジェクトは管理対象外のままです。

137