Symfony2 / Doctrine2 - ManyToOne - Inverse Seite speichern

9

Ich bin neu in Symfony and Doctrine.

Ich habe eine Entität "Benutzer" und eine Entität "Typ". Ein Benutzer kann einen Favoritentyp haben und ein Typ kann viele Benutzer haben, die diesen bestimmten Typ als Favorit haben. Also brauche ich eine Viele (User) to One (Type) Beziehung.

Ich habe es implementiert und es funktioniert gut (meistens). Aber eine Sache verstehe ich nicht.

Wenn ich so etwas mache, funktioniert es:

%Vor%

Die Objekte werden generiert und im DB gespeichert. Und die favorite_type_id ist korrekt eingestellt. Das Ändern der Eigentümerseite funktioniert also wie erwartet .

Aber wenn ich den Benutzer der inversen Seite (nur) hinzufüge und den Entity Manager lösche, wird favorite_type_id nicht gesetzt.

%Vor%

Warum ist das? Gibt es einen Grund, warum es nicht von der umgekehrten Seite funktioniert? Muss ich das wirklich manuell einstellen? Wenn ich die addUser-Methode in der Typ-Entity wie "$ user- & gt; setFavoriteType ($ this)" manipuliere, funktioniert es. Aber sollte das nicht die Aufgabe der Lehre sein?

Die Dokumentation sagt

  

Wenn eine bidirektionale Verknüpfung aktualisiert wird, überprüft Doctrine nur eine der beiden Seiten auf diese Änderungen. Dies wird die besitzende Seite des Vereins genannt.

Es scheint also das gewünschte Verhalten zu sein, stimmt das? Aber warum? Aufgrund der Leistung? Semantische Gründe?

Ich wäre froh, wenn mir jemand das erklären könnte oder mir sagen könnte, was ich falsch mache.

    
Simon H 27.09.2014, 02:27
quelle

2 Antworten

3

Sehen Sie sich die Doctrine-Dokumentation zur Kaskadierung an . . Dies sollte Ihnen helfen, schnell und einfach mit dem zu beginnen, was Sie wollen, indem Sie cascade={"persist"} hinzufügen und Ihren Cache leeren (um Doctrines Metadaten-Cache neu aufzubauen).

    
Shon M 28.09.2014 21:25
quelle
0

Dies kommt zustande, weil Doctrine bei der Berücksichtigung von Persistenz PHP-Entitäten direkt in Datenbanktabellen einbindet. In Ihrem Fall haben Benutzer und Typen konzeptionell eine Viele-zu-Eins-Beziehung, aber auf Datenbankebene wird die Beziehung vollständig in der Benutzertabelle dargestellt - ein Benutzer hat einen bevorzugten Typ, und daher hat die Benutzertabelle eine favorite_type_id -Spalte . Obwohl wir uns vorstellen können, dass Entitäten eine Liste der Benutzer haben, für die sie am beliebtesten sind, wird dies im Wesentlichen auch durch die Benutzertabelle abgeleitet. In der Tabelle Typ ist nichts enthalten.

Durch das Einrichten der Entitätszuordnung in Doctrine wird Doctrine mitgeteilt, wie die Beziehung zwischen den Entitäten ist, und Doctrine kann Ihnen bestimmte bequeme Zugriffsmethoden wie $type->getUsers() bereitstellen, ändert jedoch nicht, wie die zugrunde liegenden Daten gespeichert werden. Wenn ich $user->setFavoriteType verwende, manipuliere ich Daten, für die es eine direkte Datenbankkorrespondenz gibt, aber standardmäßig, wenn ich $type->addUser anrufe, bin ich nicht der Hauptzweck, diese Art von Call out-of-the-box zu machen ist, die hydratisierten Entitäten, mit denen Sie gerade arbeiten, auf dem neuesten Stand zu halten, ohne die Objekte einfach wegwerfen und aus der Datenbank holen zu müssen.

Natürlich hast du gesehen, dass du addUser so anpassen kannst, dass auch setFavoriteType aufgerufen wird, oder konfiguriere Kaskaden-Persistenz, wie es Shon M vorschlägt, um das Verhalten ein bisschen besser zu machen. Es mag wie eine Verschwendung von Zeit erscheinen, das von Anfang an auszulassen, aber ich vermute, dass die Doktrinenentwickler sich bewusst dafür entschieden haben, die benötigte Funktionalität auf die einfachste Art und Weise zu implementieren, während documentation und biete mehrere einfache Alternativen an, wenn Sie danach suchen, und sorgen so für jeden So oder so. Ob es nun geht oder nicht, welche Daten in der DB sind und welche Daten in PHP nach der Hydration laufen, sind technisch unterschiedliche Dinge, besonders in einem Modell wie Doctrine, wo DB-Aktivitäten aufgeschoben werden, bis der Entwickler sie anfordert, und das macht sehr viel Sinn um all das so explizit wie möglich zu machen!

    
frumious 28.09.2014 22:37
quelle