Исключение из доктрины Symfony2 при сохранении сущностей OneToMany

Я настраиваю эти объекты:

MarketMain:

class MarketMain
{
/**
* @var integer
*
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;

/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="\Acme\CMSBundle\Entity\MarketLanguage", mappedBy="marketMain", indexBy="langId", cascade="all", orphanRemoval=true, fetch="EXTRA_LAZY")
*/
private $marketLanguage;
}

MarketLanguage:

    class MarketLanguage
{
/**
* @var \Acme\CMSBundle\Entity\MarketMain
* @ORM\Id
* @ORM\ManyToOne(targetEntity="\Acme\CMSBundle\Entity\MarketMain", inversedBy="marketLanguage")
* @ORM\JoinColumn(name="market_id", referencedColumnName="id")
*/
private $marketMain;

/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="lang_id", type="integer", nullable=false)
*/
private $langId = 1;

/**
* @var string
*
* @ORM\Column(name="name", type="string", length=200, nullable=true)
*/
private $name;
}

И я хочу сохранить сущность так:

...........
$form = $this->createForm(new MarketMainType(), new MarketMain());
$form->handleRequest($request);
$marketFormData = $form->getData();

$em->persist($marketFormData);
$em->flush($marketFormData);

foreach ($marketFormData->getMarketLanguage() as $market_language)
{
$market_language->setName("My market name");
$market_language->setMarketMain($marketFormData);
$em->persist($market_language);
}

$em->flush();

Чем я получаю эту ошибку:

Объект типа Acme \ CMSBundle \ Entity \ MarketLanguage отсутствует
присвоенный идентификатор для поля «marketMain». Стратегия генерации идентификатора
для этого объекта требуется заполнить поле ID до
EntityManager # persist () вызывается. Если вы хотите автоматически генерируется
вместо идентификаторов вам нужно настроить отображение метаданных
соответственно.

Если я пытаюсь сделать $marketFormData сохраняться после каждой записи я получаю эту ошибку:

Объект типа Acme \ CMSBundle \ Entity \ MarketLanguage имеет идентификатор
через иностранную организацию Acme \ CMSBundle \ Entity \ MarketMain, однако
эта сущность не имеет самой идентичности. Вы должны позвонить
EntityManager # persist () для связанной сущности и убедитесь, что
идентификатор был сгенерирован перед попыткой сохранения
«Acme \ CMSBundle \ Entity \ MarketLanguage. В случае Post Вставить ID
Поколение (например, MySQL Auto-Increment или PostgreSQL SERIAL) это
означает, что вы должны вызвать EntityManager # flush () между обоими персистентными
операции.

Я знаю, что если я попытаюсь упорствовать $marketFormData Доктрина цикла до не знает освобожденного $marketLanguage ссылки, но если я установлю постоянство после foreach, это говорит, что у меня есть первый постоянный родительский объект. Итак, я попробовал этот код, и он работал:

...........
$form = $this->createForm(new MarketMainType(), new MarketMain());
$form->handleRequest($request);
$marketFormData = $form->getData();

$market_languages = $marketFormData->getMarketLanguage();

$marketFormData->setMarketLanguage(null);
$em->persist($marketFormData);
$em->flush($marketFormData);

$marketFormData->setMarketLanguage($market_languages);
foreach ($marketFormData->getMarketLanguage() as $market_language)
{
$market_language->setName("My market name");
$market_language->setMarketMain($marketFormData);
$em->persist($market_language);
}

$em->flush();

Но это единственный способ сохранить связанные сущности? Чтобы клонировать его с нулевым значением, сохраните родительский объект, а затем установите его обратно, добавьте ссылки и очистите все. Я думаю, что я что-то здесь упустил.

1

Решение

Я думаю, что ваши объекты отображаются неправильно. Сущность должна иметь аннотацию об идентификаторе и другую ссылку.

А также, когда у вас нет первичного ключа с автоинкрементом, необходимо объявить конструктор класса, передавая оба значения, как указано в http://doctrine-orm.readthedocs.org/en/latest/tutorials/composite-primary-keys.html

Это должно выглядеть так:

class MarketLanguage
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="market_id", type="integer", nullable=false)
*/
private $marketId;

/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="lang_id", type="integer", nullable=false)
*/
private $langId = 1;

/**
* @var \Acme\CMSBundle\Entity\MarketMain
*
* @ORM\ManyToOne(targetEntity="\Acme\CMSBundle\Entity\MarketMain", inversedBy="marketLanguage")
* @ORM\JoinColumn(name="market_id", referencedColumnName="id")
*/
private $marketMain;

/**
* @var string
*
* @ORM\Column(name="name", type="string", length=200, nullable=true)
*/
private $name;

public function __construct($marketId, $langId) {
$this->marketId = $marketId;
$this->langId = $langId;
}
}
1

Другие решения

Вы пытались удалить flush ($ marketFormData)?

$form = $this->createForm(new MarketMainType(),$marketMain);
$form->handleRequest($request);
$marketFormData = $form->getData();

$em->persist($marketFormData);
// $em->flush($marketFormData); // remove that flush

foreach ($marketFormData->getMarketLanguage() as $market_language)
{
$market_language->setName("My market name");
$market_language->setMarketMain($marketMain);
$em->persist($market_language);
}

$em->flush();

может быть проблема в том, что вы пытаетесь сбрасывать $ marketFormData, который содержит MarketLanguages, которые не сохраняются? Не уверен, что я прав, не проверял это.

РЕДАКТИРОВАТЬ, может быть, эту работу:

$form = $this->createForm(new MarketMainType(), new MarketMain());
$form->handleRequest($request);
$marketFormData = $form->getData();

foreach ($marketFormData->getMarketLanguage() as $market_language)
{
$market_language->setName("My market name");
$market_language->setMarketMain($marketMain);
}

$em->persist($marketFormData);
$em->flush($marketFormData);
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector