2012-03-28 8 views
11

erstellen Bevor ich mein Problem beschreiben, könnte es tatsächlich machen es klarer, wenn ich mit dem Fehler starten erhalte ich:Lehre viele-zu-viele-Beziehung will zweimal eine Tabelle erstellen, wenn ich eine Migration

$ ./app/console doc:mig:diff 

    [Doctrine\DBAL\Schema\SchemaException]     
    The table with name 'user_media_area' already exists. 

Das ist absolut richtig - user_media_area existiert. Ich habe es in einer früheren Migration erstellt und ich verstehe nicht, warum Symfony versucht, die Tabelle erneut zu erstellen.

Mein Problem hat etwas mit einer Viele-zu-Viele-Beziehung zu tun. Ich habe eine Tabelle mit dem Namen user, eine Tabelle mit der Bezeichnung media_area und eine Tabelle mit der Bezeichnung user_media_area.

Hier ist der Code, wo ich sagen user über media_area (Entity/User.php):

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
* @JoinTable(name="user_media_area", 
*  joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@JoinColumn(name="media_area_id", referencedColumnName="id")} 
*  ) 
*/ 
private $mediaAreas; 

Und hier ist, wo ich sagen media_area über user (Entity/MediaArea.php):

/** 
* @ORM\ManyToMany(targetEntity="User", mappedBy="users") 
*/ 
private $users; 

Interessant ist, dass, wenn ich entfernen dass JoinTable Zeug von Entity/User.php, ./app/console doctrine:migrations:diff wird wieder funktionieren:

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
*/ 
private $mediaAreas; 

Allerdings ist es ein wenig aus: es will jetzt eine neue Tabelle mit dem Namen mediaarea erstellen, die ich nicht will. Meine Tabelle existiert bereits und heißt media_area.

So wie es aussieht oder so, Symfony eine Tabelle auf diese ManyToMany Sache in meiner User Klasse, und der einzige Grund, warum das Problem verschwindet Basis zu schaffen versucht, wenn ich entferne die JoinTable ist, dass der Name der Tabelle, es will zu erstellen (mediaarea) stimmt nicht mehr mit dem tatsächlichen Namen meiner Tabelle überein (media_area). Also meine Frage ist: Warum will es überhaupt eine neue Tabelle erstellen? Was mache ich falsch?

(ich weiß, es ist möglich, dass meine Namenskonventionen ausgeschaltet sind. Symfony und Datenbank Beispiele Lehre sind frustrierende ohne Mehr Begriff Spaltennamen, so dass ich weiß nicht immer, wenn ich angeblich media_area oder mediaArea zu tun.)

Antwort

4

nach der Association Mapping Erklärung auf den offiziellen Dokumenten, die @JoinColumn und @JoinTable Definitionen sind in der Regel optional und sinnvolle Standardwerte haben, sind:

name: "<fieldname>_id" 
referencedColumnName: "id" 

Von dass wir, dass es schließen können ist wirklich kein konkreter Unterschied zwischen den beiden Implementierungen, die Sie vorgestellt haben.

Wenn es jedoch um Migration geht, ist die Erstellung der Tabelle ein ziemlich häufiges und erwartetes Verhalten. Die Sache ist, die Tabelle sollte immer gelöscht und neu erstellt werden, was nicht passiert.

Über den Tabellennamen Problem, das Standardverhalten von Doctrine 2 dazu:

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
*/ 
private $mediaAreas; 

ist zu versuchen, und erstellen Sie eine Tabelle mediaarea genannt. Wiederum vollkommen normal.

Wenn Sie einen bestimmten Namen für die Tabelle eines Unternehmens erklären wollen, sollten Sie dies tun:

/** 
* @ORM\Table(name="my_table") 
*/ 
class Something 

Ich bin mir nicht sicher, ob das Sie überhaupt hilft, aber ich denke, es bringt Sie, zumindest auf dem richtigen Weg.

+3

Warum ist dies als Antwort markiert? Es beantwortet nicht die Frage von OP, wie man die Doktrin davon abhält, diesen Fehler zu zeigen. Nach dem Hinzufügen habe ich Doctrine \ Common \ Annotations \ AnnotationException: [Semantischer Fehler] Annotation @ORM \ Table darf nicht in der Eigenschaft User :: $ mediaAreas deklariert werden. Sie dürfen diese Anmerkung nur für diese Codeelemente verwenden: CLASS. – jaycode

+0

Sie versuchen, die Annotation "@ ORM/Table" auf die Eigenschaftsebene zu setzen, während sie auf Klassenebene platziert werden sollte. Der Fehler hat weder mit der Frage noch mit der Antwort etwas zu tun. –

+0

Die richtige Anmerkung ist @ ORM/JoinTable – luliandro