Отношение "многие ко многим" в Доктрине2 приводит к ошибке дублирования при миграции


В своем проекте я создал две сущности Doctrine2, основанные на фреймворке Symfony2. Эти сущности имеют отношение "многие ко многим". Вот мои модели:

/**
 * @ORM\Entity
 * @ORM\Table(name="first")
 */
class First
{
    ...

    /**
     * @var Second[]|Collection
     *
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Second", cascade={"detach"})
     * @ORM\JoinTable(name="first_to_second",
     *      joinColumns={@ORM\JoinColumn(name="first_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="second_id", referencedColumnName="id")},
     * )
     */
    private $seconds;

    ...
}

/**
 * @ORM\Entity
 * @ORM\Table(name="second")
 */
class Second
{
    ...

    /**
     * @var First[]|Collection
     *
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\First", cascade={"remove"})
     * @ORM\JoinTable(name="first_to_second",
     *      joinColumns={@ORM\JoinColumn(name="second_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="first_id", referencedColumnName="id")},
     * )
     */
    private $firsts;

    ...
}

Когда я пытаюсь выполнить миграцию

$ php app/console doctrine:migration:diff

Произошла ошибка:

[Doctrine\DBAL\Schema\SchemaException]                       
The table with name 'first_to_second' already exists. 
Author: Albert Iskhakov, 2015-12-17

1 answers

Определения полей неверны. Вы должны определить JoinTable только одну сторону (сторону владельца) отношения и определить, какая сторона является какой, с помощью mappedBy и inversedBy.

Http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional

/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntity="Group", inversedBy="users")
     * @JoinTable(name="users_groups")
     */
    private $groups;

    public function __construct() {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

/** @Entity */
class Group
{
    // ...
    /**
     * @ManyToMany(targetEntity="User", mappedBy="groups")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

5.9.1. Владение и обратная сторона в ассоциации многих людей

Для ассоциаций "Многие ко многим" вы можете выбрать, какая организация является владельцем и какая обратная сторона. Существует очень простое семантическое правило, позволяющее решить, какая сторона более подходит для того, чтобы быть стороной-владельцем с точки зрения разработчиков. Вам нужно только спросить себя, какая организация отвечает за управление подключением, и выбрать ее в качестве стороны-владельца.

 2
Author: 1ed, 2015-12-17 07:50:19