Symfony / Doctrine:OneToMany插入导致null id
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Symfony / Doctrine:OneToMany插入导致null id相关的知识,希望对你有一定的参考价值。
我有两个实体,我正在尝试应用OneToMany / ManyToOne关系(一个游戏有很多GameContent)。
游戏
/**
* @ORMOneToMany(targetEntity="GameContent", mappedBy="game")
*/
private $contents;
public function __construct()
{
$this->contents = new ArrayCollection();
}
public function getContents()
{
return $this->contents;
}
GameContent
/**
* @ORMManyToOne(targetEntity="Game", inversedBy="contents")
*/
private $game;
以下代码将两个记录都插入到各自的表中:
$game = $form->getData();
$content = new GameContent();
$content->setType('some type');
$game->getContents()->add($content);
$em = $this->getDoctrine()->getManager();
$em->persist($content);
$em->persist($game);
$em->flush();
但是,GameContent的game_id
作为null
插入:
INSERT INTO game_content (type, game_id) VALUES (?, ?)
Parameters: { 1: 'some type', 2: null }
我也尝试过:
- 改变
persist()
的顺序 - 用
$game->getContents()->add($content)
用$game->addContents($content)
取代$this->contents[] = $content;
- 删除
persist($content)
并在游戏实体上使用cascade={"persist"}
。
为什么game_id
被插入为null?
我目前的解决方法是:
$em = $this->getDoctrine()->getManager();
$game = $form->getData();
$em->persist($game);
$content = new GameContent();
$content->setType('some type');
$content->setGame($game);
$em->persist($content);
$em->flush();
答案
你有2个解决方案:
把孩子留在控制器里
没有cascade={"persist"}
$em = $this->getDoctrine()->getManager();
// Get data
$game = $form->getData();
// Create new GameContent and hydrate
$content = new GameContent();
$content->setType('some type');
// Associate Game <> GameContent
$content->setGame($game);
// Persist GameContent
$em->persist($content);
// Persist Game and commit
$em->persist($game);
$em->flush();
坚持级联的孩子
与cascade={"persist"}
在OneToMany关系。
添加setGame()
函数,强制关联:
$game->addContent($this);
并删除持久性:
$em = $this->getDoctrine()->getManager();
// Get data
$game = $form->getData();
// Create new GameContent and hydrate
$content = new GameContent();
$content->setType('some type');
// Associate Game <> GameContent
$content->setGame($game);
// Persist Game and commit
$em->persist($game);
$em->flush();
我认为错误也是由于持久性在游戏中的定位。
另一答案
除了接受的答案之外,我的下一步是创建一个表单来处理GameContent数据,这导致了进一步的更改和一些简化的逻辑。
我现在在setGame()
Game::addContent()
,所以我在$game->addContent($this);
删除了GameContent::setGame()
。
游戏
/**
* @var ArrayCollection
* @ORMOneToMany(targetEntity="GameContent", mappedBy="game", cascade={"persist"})
*/
private $contents;
public function __construct()
{
$this->contents = new ArrayCollection();
}
public function getContents()
{
return $this->contents;
}
public function addContent(GameContent $content)
{
$this->contents->add($content);
$content->setGame($this);
return $this;
}
public function removeContent(GameContent $content)
{
$this->contents->removeElement($content);
return $this;
}
GameContent
/**
* @ORMManyToOne(targetEntity="Game", inversedBy="contents")
*/
private $game;
public function setGame(Game $game)
{
$this->game = $game;
return $this;
}
/**
* @return Game
*/
public function getGame()
{
return $this->game;
}
真实的表单处理逻辑将如下所示:
$game = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($game);
$em->flush();
更多信息请访问:http://symfony.com/doc/2.8/form/form_collections.html(参见Doctrine:级联关系并保存“反向”方面)。
以上是关于Symfony / Doctrine:OneToMany插入导致null id的主要内容,如果未能解决你的问题,请参考以下文章