Grundlegendes zu Doctrine Cascade Operations

72

Ich möchte mein Verständnis von Kaskadenoperationen auf Doktrinassoziationen überprüfen. Für diese Frage habe ich zwei Modelle: Customerund Insuree.

Wenn ich eine Viele-zu-Viele-Beziehung zwischen einem Customerund Insureeund einer Menge definiere cascade{"all"}, verstehe ich, dass dies:

  • Durch Hinzufügen eines neuen Versicherten zu einem Kunden bleibt dieser Versicherte bestehen und es wird eine Zuordnung in der Join-Tabelle erstellt.
  • Durch das Entfernen eines Versicherten aus der Sammlung wird der Versicherte vom Kunden und der Kunde vom Versicherten getrennt.
  • Durch das Löschen des Kunden werden alle mit dem Kunden verbundenen Versicherten gelöscht.

Dies ist die Definition des Vereins auf 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;

Wenn ich die umgekehrte Viele-zu-Viele-Beziehung zwischen einem Insureeund Customerund einer Menge definiere cascade{"all"}, verstehe ich, dass dies:

  • Durch Hinzufügen eines neuen Kunden zu einem Versicherten bleibt dieser Kunde bestehen und es wird eine Zuordnung in der Join-Tabelle erstellt.
  • Durch das Entfernen eines Kunden aus der Sammlung wird der Kunde vom Versicherten und der Versicherte vom Kunden getrennt.
  • Durch das Löschen des Versicherten werden alle damit verbundenen Kunden gelöscht.

Dies ist die Definition des Vereins auf Insurees.

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

Wenn ich dann die Beziehung so definiere, dass sie beim Fortbestehen, Zusammenführen und Trennen kaskadiert - das Löschen des Versicherten löscht nicht alle zugeordneten Kunden - werden nur die Assoziationen zwischen dem Versicherten und seinen Kunden entfernt?

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

quelle
1
Können Sie nicht überprüfen, ob Ihr Verständnis der kaskadierenden Beziehungen korrekt ist, indem Sie einige Customers und Insurees erstellen und mit dem Löschen / Hinzufügen von Datensätzen beginnen?
undefiniert

Antworten:

157

bestehen & entfernen

Sie haben Recht cascade={"persist"} , dass die Entität A, Doctrine auch alle B-Entitäten in der Sammlung bestehen bleibt.

Sie haben auch Recht damit cascade={"remove"}, dass das Entfernen von Entität A, Doctrine auch alle B-Entitäten in der Sammlung entfernt.
Ich bezweifle jedoch, dass Sie dies jemals für eine ManyToMany-Zuordnung verwenden möchten, da beim Entfernen von Entität A, die diese Operation auf alle B-Entitäten kaskadiert, diese B-Entitäten möglicherweise anderen A-Entitäten zugeordnet werden.

trennen & zusammenführen

Sie haben nicht Recht mit cascade={"detach"}und cascade={"merge"}:

Das Hinzufügen / Entfernen von Entitäten zur Sammlung ist etwas, das Sie (in Ihrem Code) tun müssen. Lesen Sie hier darüber .

Ablösen bedeutet, dass Sie eine Entität vom EntityManager trennen. Der EntityManager verwaltet diese Entität nicht mehr. Dadurch wird eine getrennte Entität mit einer neu instanziierten Entität identisch, mit der Ausnahme, dass sie sich bereits in der Datenbank befindet (aber Sie haben den EntityManager darauf aufmerksam gemacht).

Mit anderen Worten: cascade={"detach"}bedeutet, dass durch das Trennen von Entität A und Doctrine auch alle B-Entitäten in der Sammlung getrennt werden.

Zusammenführen ist das Gegenteil von Trennen : Sie führen eine getrennte Entität wieder in den EntityManager ein.
Beachten Sie, dass merge()ein neues verwaltetes Objekt tatsächlich zurückgegeben wird. Das getrennte Objekt, das Sie an es übergeben haben, bleibt nicht verwaltet.

Jasper N. Brouwer
quelle
Es ist zu beachten, dass beim Aufrufen merge()die nicht verwaltete Entität die Eigenschaften der verwalteten Entität überschreibt. Anschließend persist()führt die jetzt verwaltete Entität eine Aktualisierung für die Tabelle dieser Entität durch. Dies kann zu unerwartetem Datenverlust führen.
Kevin Mesiab