问题描述
在我描述我的问题之前,如果我从错误中得到的话可能会更清楚: $ ./app/console doc:mig:diff
[Doctrine\DBAL\Schema\SchemaException]
名称为user_media_area的表已存在。
这是绝对真实的 - user_media_area
确实存在。我在以前的迁移中创建了它,我不明白为什么Symfony正试图再次创建表。
我的问题与多对多关系有关,很多关系。我有一个名为用户
的表,一个名为 media_area
的表和一个名为 user_media_area
。
这里是代码,我告诉用户
关于 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;
这里是我告诉 media_area
code>用户( Entity / MediaArea.php
):
/ **
* @ ORM\ManyToMany(targetEntity =User,mappedBy =users)
* /
private $ users;
有趣的是,如果我删除那个 JoinTable
来自 Entity / User.php
, ./ app / console doctrine:migrations:diff
的内容可以再次工作: / p>
/ **
* @ ORM\ManyToMany(targetEntity =MediaArea,inversedBy =mediaAreas)
* /
private $ mediaAreas;
然而,它有点偏离:现在想创建一个新的表$ code > mediaarea ,我不想要。我的表已经存在,它被称为 media_area
。
所以看起来像是两种方式,Symfony正试图创建一个基于这个 ManyToMany
在我的用户
类中的表,这个问题消除了唯一的原因,当我删除 JoinTable
是要创建的表的名称( mediaarea
)不再符合我的表的实际名称 media_area
)。
所以我的问题是:为什么要创建一个新的表?我做错了什么?
(我知道我的命名约定可能是关闭的。Symfony和Doctrine的数据库示例令人沮丧地缺少多项列名字,所以我不总是知道我是否应该做 media_area
或 mediaArea
。)
根据官方文档的说明, @JoinColumn
和 @JoinTable
定义通常是可选的,并具有明智的默认值,为:
name: < fieldname> _id
referencedColumnName:id
从中我们可以得出结论在你提出的两个实现之间真的没有具体的区别。
然而,当谈到mi gration,表的创建是一个很常见和预期的行为。事实是表应该总是被删除并再次创建,这不是发生的。
关于表名问题,Doctrine 2关于这个的默认行为: p>
/ **
* @ ORM\ManyToMany(targetEntity =MediaArea,inversedBy =mediaAreas)
* /
private $ mediaAreas;
是尝试创建一个名为 mediaarea
。再次,完全正常。
如果要为实体的表格声明特定的名称,您应该这样做:
/ **
* @ ORM\Table(name =my_table)
* /
class Something
我不知道这是否可以帮助您,但我猜这至少会让您在右边轨道。
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.
这篇关于Doctrine多对多关系想要在创建迁移时创建一个表两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!