Как бороться с ассоциацией на составных ключевых сущностях с Doctrine2? - PullRequest
7 голосов
/ 03 августа 2011

Скажите, что у меня есть предложение, которое может иметь 1-й диапазон. Сразу же вы думаете: «поместите offer_id в Range».

Но мое предложение имеет составной первичный ключ (состоит из двух полей). Столбец идентификатора AUTOINCREMENT отсутствует.

Документация Doctrine2 мало говорит об этом конкретном случае, вот мои сущности:

<?php
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Table()
 * @ORM\Entity
 */
class Offer
{
    /**
     * @var Site $site
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Site")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="id")
     */
        private $site;

    /**
     * @var string $pouet
     * @ORM\Id
     * @ORM\Column(name="pouet", type="string", length=255)
     */
    private $pouet;
}

<?php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="RangeItem")
 * @ORM\Entity
 */
class Range
{
    /**
     * @todo This is test code only do not push me :-)
     * @var ArrayCollection
     * @ORM\ManyToOne(targetEntity="Offer")
     */
    private $offers;
}

Я получаю эту ошибку:

[Учение \ ORM \ ORMException]
Имя столбца id ссылка на отношение от Pouet \ MyBundle \ Entity \ Range to Pouet \ MyBundle \ Entity \ Предложение делает не существует.

Это имеет смысл, но как я могу решить эту проблему? Запрещено ли в Таблице с составным первичным ключом иметь ассоциации?

Ответы [ 2 ]

4 голосов
/ 14 мая 2018

Я считаю, что решение состоит в том, чтобы отразить первичный ключ (PK) для внешнего ключа (FK). И.Е. для каждого столбца, составляющего PK (site, pouet), необходимо иметь одинаковые столбцы для связанной сущности.

Вы можете сделать это, используя аннотацию JoinColumns (или эквивалент в YAML / XML) с JoinColumn для каждой части составного FK:

/**
 * @ORM\Table(name="RangeItem")
 * @ORM\Entity
 */
class Range
{
    /**
     * @todo This is test code only do not push me :-)
     * @var ArrayCollection
     * @ORM\ManyToOne(targetEntity="Offer")
     * @ORM\JoinColumns(
     *     @ORM\JoinColumn(name="site_id", referencedColumnName="site_id"),
     *     @ORM\JoinColumn(name="pouet", referencedColumnName="pouet")
     * )
     */
    private $offers;
}

Я надеюсь, что это может помочь кому-то, кто все еще борется с этой проблемой.

1 голос
/ 03 августа 2011

Вы должны иметь возможность использовать аннотацию @JoinColumn в классе Range, чтобы указать, какой идентификатор использовать:

/**
 * @ORM\ManyToOne(targetEntity="Offer")
 * @ORM\JoinColumn(name="offer_pouet", referencedColumnName="pouet")
 */
private $offers;

Поскольку значения по умолчанию для @JoinColumn, если вы не укажете их, будут offer_id и id, соответственно, вам нужно указать вручную (здесь я делаю небольшое предположение, что pouet является уникальным значением для вашего Offer класса).

РЕДАКТИРОВАТЬ: на основе вашего комментария я нашел учебное пособие на сайте проекта Doctrine для Составной первичный ключ . Отношение сущности имеет mappedBy для одного ключа и indexBy для другого. Надеюсь, это поможет.

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