2012-03-28 11 views
11

Antes de describir mi problema, en realidad podría hacerlo más claro si comienzo con el error que estoy recibiendo:Doctrina relación muchos-a-muchos quiere crear una mesa dos veces cuando creo una migración

$ ./app/console doc:mig:diff 

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

Eso es absolutamente cierto: user_media_area existe. Lo creé en una migración anterior y no entiendo por qué Symfony intenta crear la tabla nuevamente.

Mi problema tiene algo que ver con una relación de muchos a muchos. Tengo una tabla llamada user, una tabla llamada media_area y una tabla llamada user_media_area.

Aquí está el código donde yo digo user sobre 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; 

Y aquí es donde yo digo media_area sobre user (Entity/MediaArea.php):

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

Lo que es interesante es que si quito que JoinTable cosas de Entity/User.php, ./app/console doctrine:migrations:diff funcionarán de nuevo:

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

Sin embargo, es un poco fuera: ahora quiere crear una nueva tabla llamada mediaarea, lo que no quiero. Mi tabla ya existe y se llama media_area.

por lo que parece en cualquier caso, Symfony está tratando de crear una tabla basada en este ManyToMany cosa en mi clase User, y la única razón el problema desaparece cuando quito la JoinTable es que el nombre de la tabla que quiere para crear (mediaarea) ya no coincide con el nombre real de mi tabla (media_area).

Así que mi pregunta es: ¿Por qué quiere crear una nueva tabla? ¿Qué estoy haciendo mal?

(sé que es posible que mis convenciones de nombres están apagados. Symfony y ejemplos de bases de datos de Doctrine son frustrante carente de nombres de columnas múltiples plazo, por lo que no siempre saben si se supone que debo hacer media_area o mediaArea.)

Respuesta

4

de acuerdo con la explicación Association Mapping en los documentos oficiales, los @JoinColumn y @JoinTable definiciones suelen ser opcionales y tienen valores por defecto sensibles, siendo:

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

Desde que podemos concluir que hay es realmente sin diferencia concreta entre las dos implementaciones que presentó.

Sin embargo, cuando se trata de migración, la creación de la tabla es un comportamiento bastante común y esperado. La cuestión es que la tabla siempre debería eliminarse y crearse de nuevo, lo que no está sucediendo.

Sobre la cuestión nombre de la tabla, el comportamiento por defecto de la Doctrina 2 en esto:

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

es tratar de crear una tabla llamada mediaarea. De nuevo, perfectamente normal.

Si desea declarar un nombre específico para la mesa de una entidad, que debe hacer esto:

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

No estoy seguro de si eso le ayuda en absoluto, pero supongo que lo pone, al menos, en el camino correcto.

+3

¿Por qué está marcado como la respuesta? No responde la pregunta de OP sobre cómo evitar que la doctrina muestre ese error. Al agregar esto, recibí Doctrine \ Common \ Annotations \ AnnotationException: [Semantical Error] Annotation @ORM \ Table no puede declararse en la propiedad User :: $ mediaAreas. Solo puede usar esta anotación en estos elementos de código: CLASS. – jaycode

+0

Está intentando colocar la anotación '@ ORM/Table' en el nivel de propiedad, mientras que debe colocarse en el nivel de clase. El error no tiene nada que ver ni con la pregunta ni con la respuesta. –

+0

La anotación correcta es @ ORM/JoinTable – luliandro

Cuestiones relacionadas