本文介绍了Doctrine多对多关系想要在创建迁移时创建一个表两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我描述我的问题之前,如果我从错误中得到的话可能会更清楚:

  $ ./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多对多关系想要在创建迁移时创建一个表两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 10:48