Before I describe my problem, it might actually make it clearer if I start with the error I'm getting:
$ ./app/console doc:mig:diff
[Doctrine\DBAL\Schema\SchemaException]
The table with name 'user_media_area' already exists.
That's absolutely true - user_media_area
does exist. I created it in a previous migration and I don't understand why Symfony is trying to create the table again.
My problem has something to do with a many-to-many relationship. I have a table called user
, a table called media_area
and a table called user_media_area
.
Here's the code where I tell user
about 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;
And here's where I tell media_area
about user
(Entity/MediaArea.php
):
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="users")
*/
private $users;
What's interesting is that if I remove that JoinTable
stuff from Entity/User.php
, ./app/console doctrine:migrations:diff
will work again:
/**
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
*/
private $mediaAreas;
However, it's a little off: it now wants to create a new table called mediaarea
, which I don't want. My table already exists and it's called media_area
.
So it looks like either way, Symfony is trying to create a table based on this ManyToMany
thing in my User
class, and the only reason the problem goes away when I remove the JoinTable
is that the name of the table it wants to create (mediaarea
) no longer matches the actual name of my table (media_area
).
So my question is: Why does it want to create a new table at all? What am I doing wrong?
(I know it's possible that my naming conventions are off. Symfony and Doctrine's database examples are frustratingly devoid of multi-term column names, so I don't always know if I'm supposed to do media_area
or mediaArea
.)
According to the Association Mapping explanation on the official docs, the @JoinColumn
and @JoinTable
definitions are usually optional and have sensible default values, being:
name: "<fieldname>_id"
referencedColumnName: "id"
From that we can conclude that there is really no concrete difference between the two implementations you presented.
However, when it comes to migration, the creation of the table is a pretty common and expected behaviour. The thing is the table should always get deleted and created again, which is not happenning.
About the table name issue, the default behaviour of Doctrine 2 about this:
/**
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
*/
private $mediaAreas;
Is to try and create a table called mediaarea
. Again, perfectly normal.
If you want to declare a specific name for the table of an entity, you should do this:
/**
* @ORM\Table(name="my_table")
*/
class Something
I'm not sure if that helps you at all, but I guess it puts you, at least, on the right track.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With