我配置了这个实体:
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。标识符生成策略 对于此实体,需要先填充ID字段 调用EntityManager#persist()。如果要自动生成 您需要调整元数据映射 相应
如果我在foreach语句之后试图$marketFormData
继续存在,我会收到此错误:
Acme \ CMSBundle \ Entity \ MarketLanguage类型的实体具有标识 但是,通过外国实体Acme \ CMSBundle \ Entity \ MarketMain 这个实体本身没有身份。你必须打电话 EntityManager#persist()在相关实体上并确保一个 在尝试持久化之前生成了标识符 'Acme的\ CMSBundle \实体\ MarketLanguage'。如果是Post Insert ID 生成(如MySQL Auto-Increment或PostgreSQL SERIAL)这个 意味着你必须在两个persist之间调用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();
但这只是坚持相关实体的方法吗?要将其克隆设置为null,请保留父实体,然后将其设置回来,添加引用并刷新所有内容。我想我在这里错过了什么。
答案 0 :(得分:1)
我认为您的实体映射错误。实体必须具有关于ID的注释和关系的另一个注释。
而且,当你没有自动增量的主键时,必须声明类构造函数,传递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 :(得分:0)
您是否尝试过删除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);