I configure this entities:
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;
}
And I want to save entity like this:
...........
$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();
Than I get this error:
Entity of type Acme\\CMSBundle\\Entity\\MarketLanguage is missing an assigned ID for field 'marketMain'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
If I trying to do $marketFormData
persist after foreach statment I get this error:
Entity of type Acme\\CMSBundle\\Entity\\MarketLanguage has identity through a foreign entity Acme\\CMSBundle\\Entity\\MarketMain, however this entity has no identity itself. You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'Acme\\CMSBundle\\Entity\\MarketLanguage'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
I know that If I try to persist $marketFormData
before loop doctrine does not know the releated $marketLanguage
references, but if I set persist after the foreach it says taht I have first persist parent entity. So I tried this code and it worked:
...........
$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();
But it is only way to persist related entities? To clone it set to null, persist parent entity, and then set it back, add references and flush all. I think I have missed something here.
I think that your entities is mapped wrong. The entity must have an annotation about ID and another to relation.
And also, when you don't have a primary key with autoincrement, it is necessary declare the class constructor, passing both values as mentioned in http://doctrine-orm.readthedocs.org/en/latest/tutorials/composite-primary-keys.html
It should look like this:
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;
}
}
Did you try remove 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();
maybe problem is that you are trying flush $marketFormData which contains MarketLanguages which are not persised ? Not sure am i right, didn't tested this.
EDIT maybe this work:
$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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.