Doctrine2.0: Ошибка - столбец указан дважды - PullRequest
0 голосов
/ 20 июля 2011

В Doctrine2.0.6 я получаю сообщение об ошибке: «Colour VoucherId указан дважды».

Рассматриваются следующие модели:

  • Корзина
  • BasketVoucher
  • Ваучер

Корзина ссылается на BasketVoucher.

Ваучер ссылается на BasketVoucher.

В Voucher и BasketVoucher есть поле с именем VoucherId.Это определено в обеих моделях и существует с одинаковым именем в обеих таблицах БД.

При сохранении новой записи BasketVoucher возникает ошибка:

$basketVoucher = new BasketVoucher;
$basketVoucher->setVoucherId($voucherId);
$basketVoucher->setBasketId($this->getBasket()->getBasketId());
$basketVoucher->setCreatedDate(new DateTime("now"));
$em->persist($basketVoucher);
$em->flush();

Я проверил модели и VoucherIdне определяется дважды.Тем не менее, он используется в отображении.Вот почему Doctrine считает, что поле дублировано?

Вот соответствующий код - я не вставил модели полностью, так как большая часть кода - get / set.

Basket

/**
 * @OneToMany(targetEntity="BasketVoucher", mappedBy="basket")
 * @JoinColumn(name="basketId", referencedColumnName="BasketId")
 */
private $basketVouchers;

public function getVouchers()
{
    return $this->basketVouchers;
}

BasketVoucher

/**
 * @ManyToOne(targetEntity="Basket", inversedBy="basketVouchers")
 * @JoinColumn(name="basketId", referencedColumnName="BasketId")
 */
private $basket;

public function getBasket()
{
    return $this->basket;
}

/**
 * @OneToOne(targetEntity="Voucher", mappedBy="basketVoucher")
 * @JoinColumn(name="voucherId", referencedColumnName="VoucherId")
 */
private $voucherEntity;

public function getVoucher()
{
    return $this->voucherEntity;
}

Ваучер

/**
 * @OneToOne(targetEntity="BasketVoucher", inversedBy="voucherEntity")
 * @JoinColumn(name="voucherId", referencedColumnName="VoucherId")
 */
private $basketVoucher;

public function getBasketVoucher()
{
    return $this->basketVoucher;
}

Есть идеи?

РЕДАКТИРОВАТЬ: Я обнаружил, что та же проблема возникает с другиммодель, когда я сохраняю это в первый раз.Я устанавливаю первичный ключ вручную.Кажется, что основной проблемой является сохранение отношения внутри объекта.

В этом случае у меня есть поле - DraftOrderId - которое используется в качестве первичного ключа в трех моделях.Первая модель - DraftOrder - имеет DraftOrderId в качестве первичного ключа, который является автоматически увеличивающимся значением.Две другие модели - DraftOrderDeliveryAddress и DraftOrderBillingAddress - также используют DraftOrderId в качестве первичного ключа, но он не увеличивается автоматически.

В результате возникает одна из следующих проблем:

  1. Если я сохраню сущность адреса доставки с идентификатором черновика заказа и установлю его как постоянный, я получу ошибку: столбец DraftOrderId указан дважды.Код:

    try {
        $addressEntity->getDraftOrderId();
    } catch (\Doctrine\ORM\EntityNotFoundException $e) {
        if ($addressType == "delivery") {
            $addressEntity = new Dpp\DraftOrderDeliveryAddress;
        } elseif ($addressType == "billing") {
            $addressEntity = new Dpp\DraftOrderBillingAddress;
        }
        $addressEntity->setDraftOrderId($draftOrder->getDraftOrderId());
        $em->persist($addressEntity);
    }
    

(Было бы также полезно узнать, существует ли лучший способ проверить, существует ли связанная сущность, вместо того, чтобы перехватывать исключение при попытке получить значение.)

  1. Если я удаляю строку, которая устанавливает идентификатор чернового заказа, я получаю сообщение об ошибке: У объекта типа Dpp \ DraftOrderDeliveryAddress отсутствует назначенный идентификатор.

  2. Если я сохраняю строку, которая устанавливает идентификатор чернового порядка, но удаляю постоянную строку, и позже я также сохраняю строки в коде, который устанавливает поля имени и адреса, я не получаю ошибку - ноданные не сохраняются в базе данных.Я использую flush () после установки всех полей - я просто не использую persist ().В предыдущих примерах я использую функцию persist () - я просто пытаюсь понять, как это может работать.

Я могу вставить больше кода, если это поможет.

1 Ответ

0 голосов
/ 21 июля 2011

Я думаю, что я это исправил! Пара выводов:

  • Для первичного ключа, который не является автоинкрементным значением, необходимо использовать:

    @ GeneratedValue (стратегия = "ИДЕНТИФИКАЦИЯ")

  • Вы также должны явно установить сопоставленные объекты при их создании в первый раз. Сначала я пытался создать адресную сущность напрямую, но я не устанавливал сопоставленную сущность в родительской модели для ссылки на адресную сущность. (если это имеет смысл)

Я вполне уверен, что это было в основном из-за отсутствия ключевого слова IDENTITY, которое по какой-то причине либо говорило, что ключ не был установлен, либо говорило, что оно было установлено дважды.

...