Doctrine ORM 无法从 MySQL DB 中删除实体

问题描述 投票:0回答:1

我正在尝试清除实体集合。这是我的关系方案:

Game <-> GameQuest[]

Player <-> PlayerGameQuestLink[]

PlayerGameQuestLink 实体具有一些关于每个玩家的任务何时激活、完成等的元数据。 Player 侧的级联未设置

这是我的关系的定义方式:

/**
 * @ORM\OneToMany(targetEntity="App\Entity\PlayerGameQuestLink", mappedBy="player")
 */
 private $gameQuestLinks;

这是我的

PlayerGameQuestLink
类,没有 getter 和 setter:

namespace App\Entity;
    
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="player_retailer_game_quest_link")
 */
class PlayerRetailerGameQuestLink
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private int $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\PlayerRetailer", inversedBy="gameQuestLinks")
     */
    private $player;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\GameQuest")
     */
    private $gameQuest;
    
    /**
     * @ORM\Column(type="datetime", nullable="true")
     */
    private $activatedAt = null;

    /**
     * @ORM\Column(type="datetime", nullable="true")
     */
    private $doneAt = null;
    
    /**
     * @ORM\Column(type="datetime", nullable="true")
     */
    private $completedAt = null;

这里是删除失败的测试代码,没有任何异常和错误:

    public function resetGameQuests(Game $game)
    {
        $players = $game->getPlayers();
        /**
         * @var Player $player
         */
        foreach ($players as $player) {
            $player->getGameQuestLinks()->forAll(function($index, $link) {
                $this->em->remove($link);
            });
            //$player->getGameQuestLinks()->clear();
            //$this->em->persist($player);
        }
        $this->em->flush();

//       $gameQuests = $game->getGameQuests()->toArray();
//        foreach ($gameQuests as $gameQuest) {
//            $this->em->remove($gameQuest);
//        }
//        $game->getGameQuests()->clear();
//
//        $this->em->flush();

//        $this->createGameQuests($game);
    }

我尝试在

Doctrine ORM
代码中调试它,放置断点。

我看到它确实提交了正确的 SQL 语句。但是,一旦

commit()
在 PDO 连接上返回成功结果,数据库表 中的所有条目都会使用不同的 id 重新创建。我知道这听起来很奇怪,但这是真的。

更奇怪的是,当我将 SQL 语句 (

DELETE FROM player_game_quest_link WHERE id = N;
) 复制并粘贴到 MySQL Workbench SQL 编辑器时,它们做得很好。

我尝试手动运行事务中的 DELETE 语句 - 删除成功。另外,我尝试暂时编辑 Doctrine 的代码并删除

$conn->beginTransaction()
$conn->commit()
调用,还添加了
$conn->setAutocommit(true)
- 但错误仍然存在,所以它绝对与事务无关。

还尝试在

UnitOfWork
commit()
方法的其他部分放置断点,以查看是否有任何插入或集合更新 - 没有触发任何内容。

最后,我在

vendor/doctrine/dbal/src/Connection.php
方法中的
insert()
文件中放置了一个断点 - 以确保在请求期间不会调用它。确实不是。

这可能是一些罕见的 SQL 驱动程序问题吗?

我的

Doctrine
版本是
2.7.1
Symfony
版本是
5.3
MySQL Server
版本是
8.0.36
PHP
版本是
8.3.2
。我正在
Windows 10 1909
上运行它。

如果可以请帮忙调试

php mysql symfony doctrine-orm doctrine
1个回答
0
投票

我找到了解决方案。问题出在这段代码中:

$player->getGameQuestLinks()->forAll(function($index, $link) {
    $this->em->remove($link);
});

foreach
无法按照我的想法使用持久集合,而无需先将其转换为带有
toArray()
的数组,因此我仅删除 one 第一个玩家的链接。我以为的“行重新创建”实际上是部分删除(因为我测试的游戏有 12 名玩家,每个玩家 100 个任务,并且 MySQL Workbench 中为了性能而将结果限制设置为 100 行)。

正确的代码是这样的:

foreach ($players as $player) {
    $player->getGameQuestLinks()->clear();
}
$this->em->flush();
© www.soinside.com 2019 - 2024. All rights reserved.