Я настраиваю эти объекты:
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();
Но это единственный способ сохранить связанные сущности? Чтобы клонировать его с нулевым значением, сохраните родительский объект, а затем установите его обратно, добавьте ссылки и очистите все. Я думаю, что я что-то здесь упустил.
Я думаю, что ваши объекты отображаются неправильно. Сущность должна иметь аннотацию об идентификаторе и другую ссылку.
А также, когда у вас нет первичного ключа с автоинкрементом, необходимо объявить конструктор класса, передавая оба значения, как указано в 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;
}
}
Вы пытались удалить 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);