Symfony / Doctrine: OneToMany insert的结果是空id



我有两个实体,我正在尝试将OneToMany/ManyToOne关系应用于(一个游戏有许多游戏内容(。

游戏

/**
 * @ORMOneToMany(targetEntity="GameContent", mappedBy="game")
 */
private $contents;
public function __construct()
{
    $this->contents = new ArrayCollection();
}
public function getContents()
{
    return $this->contents;
}

游戏内容

/**
 * @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();

但是,游戏内容的game_idnull插入:

INSERT INTO game_content (type, game_id) VALUES (?, ?)
Parameters: { 1: 'some type', 2: null }

我也试过:

  • 更改persist()顺序
  • 通过执行$this->contents[] = $content;$game->getContents()->add($content)替换为$game->addContents($content)
  • 删除persist($content)并在游戏实体上cascade={"persist"}

为什么game_id入为空?


我目前的解决方法是:

$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"}一对多关系。

添加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();

我认为错误也是由于坚持在游戏中的定位。

添加 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();

请注意,今天(原则 2.7.1(,make:entity 实用程序创建为您执行此操作的方法,在您的情况下,您的游戏实体上会有这样的方法:

public function addContent(GameContent $content): self
{
    $this->contents->add($content);
    $content->setGame($this); // <-- IMPORTANT PART IS HERE
    return $this;
}

然后,在游戏中调用它就可以完成这项工作:

this->addContent((new GameContent())->setType('some type'));

除了公认的答案之外,我的下一步是创建一个表单来处理游戏内容数据,这导致了进一步的更改和一些简化的逻辑。

我现在setGame() Game::addContent(),所以我在GameContent::setGame()中删除了$game->addContent($this);

游戏

/**
 * @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;
}

游戏内容

/**
 * @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(参见学说:级联关系和保存"反向"方(。

相关内容

  • 没有找到相关文章

最新更新