在创建迁移时,Doctrine多对多关系想要创建一个表两次

Jas*_*ett 11 doctrine symfony

在我描述我的问题之前,如果我从我得到的错误开始,它实际上可能会更清楚:

$ ./app/console doc:mig:diff

  [Doctrine\DBAL\Schema\SchemaException]                 
  The table with name 'user_media_area' already exists.  
Run Code Online (Sandbox Code Playgroud)

这绝对是真的 - user_media_area确实存在.我在之前的迁移中创建了它,我不明白为什么Symfony会再次尝试创建表.

我的问题与多对多关系有关.我有一个叫做的表user,一个叫做media_area的表和一个叫做的表user_media_area.

此处,我告诉代码usermedia_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;
Run Code Online (Sandbox Code Playgroud)

这里的地方我告诉media_areauser(Entity/MediaArea.php):

/** 
 * @ORM\ManyToMany(targetEntity="User", mappedBy="users")
 */
private $users;
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我删除那些JoinTable东西Entity/User.php,./app/console doctrine:migrations:diff将再次工作:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;
Run Code Online (Sandbox Code Playgroud)

但是,它有点偏离:它现在想要创建一个名为的新表mediaarea,我不想要它.我的表已经存在并被调用media_area.

所以它看起来像两种方式,Symfony试图ManyToMany在我的User类中创建一个基于这个东西的表,并且当我删除它时问题消失的唯一原因JoinTable是它想要创建的表的名称(mediaarea)不再匹配我的表的实际名称(media_area).

所以我的问题是:为什么要创建一个新表呢?我究竟做错了什么?

(我知道这可能是我的命名约定关闭.Symfony和学说的数据库实例是令人沮丧的缺乏多项列名的,所以我总是不知道如果我应该做的media_areamediaArea).

Dan*_*iro 5

根据官方文档上的Association Mapping@JoinColumn解释,和@JoinTable定义通常是可选的,并且具有合理的默认值,即:

name: "<fieldname>_id"
referencedColumnName: "id"
Run Code Online (Sandbox Code Playgroud)

由此我们可以得出结论,您提供的两种实现之间实际上没有具体区别。

然而,当涉及到迁移时,表的创建是一种非常常见和预期的行为。问题是该表应该总是被删除并再次创建,但这并没有发生。

关于表名问题,Doctrine 2 的默认行为是这样的:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;
Run Code Online (Sandbox Code Playgroud)

就是尝试创建一个名为 的表mediaarea。再说一次,完全正常。

如果你想为实体的表声明一个特定的名称,你应该这样做:

/**
 * @ORM\Table(name="my_table")
 */
class Something
Run Code Online (Sandbox Code Playgroud)

我不确定这是否对您有帮助,但我想它至少会让您走上正确的道路。

  • 为什么将其标记为答案?它没有回答OP关于如何阻止学说显示该错误的问题。添加此内容后,我得到了 Doctrine\Common\Annotations\AnnotationException :[语义错误] 不允许在属性 User::$mediaAreas 上声明注释 @ORM\Table。您只能在这些代码元素上使用此注释:CLASS。 (4认同)