Доктрина "многие ко многим" хочет создать таблицу дважды при создании миграции - PullRequest
11 голосов
/ 29 марта 2012

Прежде чем я опишу свою проблему, она может проясниться, если я начну с ошибки, которую я получаю:

$ ./app/console doc:mig:diff

  [Doctrine\DBAL\Schema\SchemaException]                 
  The table with name 'user_media_area' already exists.  

Это абсолютно верно - user_media_area существует. Я создал его в предыдущей миграции, и я не понимаю, почему Symfony пытается создать таблицу снова.

Моя проблема связана с отношениями "многие ко многим". У меня есть таблица с именем user, таблица с именем media_area и таблица с именем user_media_area.

Вот код, где я говорю user о 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 о user (Entity/MediaArea.php):

/** 
 * @ORM\ManyToMany(targetEntity="User", mappedBy="users")
 */
private $users;

Интересно то, что если я удалю JoinTable материал из Entity/User.php, ./app/console doctrine:migrations:diff снова будет работать:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;

Однако, это немного не так: теперь он хочет создать новую таблицу с именем mediaarea, которая мне не нужна. Моя таблица уже существует и называется media_area.

Похоже, в любом случае Symfony пытается создать таблицу на основе этого ManyToMany в моем классе User, и единственная причина, по которой проблема исчезает, когда я удаляю JoinTable, заключается в том, что имя таблицы, которую он хочет создать (mediaarea), больше не соответствует реальному имени моей таблицы (media_area).

Итак, мой вопрос: Почему он вообще хочет создать новую таблицу? Что я делаю не так?

(Я знаю, что, возможно, мои соглашения об именах отключены. Примеры баз данных Symfony и Doctrine разочарованно лишены многострочных имен столбцов, поэтому я не всегда знаю, должен ли я делать media_area или mediaArea.)

1 Ответ

4 голосов
/ 03 апреля 2012

Согласно объяснению Association Mapping на официальных документах, определения @JoinColumn и @JoinTable обычно являются необязательными и имеют разумные значения по умолчанию:

name: "<fieldname>_id"
referencedColumnName: "id"

Из этого можно сделать вывод, что на самом деле нет конкретной разницы между двумя представленными вами реализациями.

Однако, когда дело доходит до миграции, создание таблицы является довольно распространенным и ожидаемым поведением. Дело в том, что таблицу всегда нужно удалять и создавать заново, чего не происходит.

О проблеме с именем таблицы, поведение Doctrine 2 по умолчанию:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;

Попытка создать таблицу с именем mediaarea. Опять же совершенно нормально.

Если вы хотите объявить конкретное имя для таблицы сущности, вы должны сделать это:

/**
 * @ORM\Table(name="my_table")
 */
class Something

Я не уверен, поможет ли это вам вообще, но, полагаю, это поставит вас, по крайней мере, на правильный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...