实体删除和外键约束违规问题

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

首先,我是 Symfony 和 Doctrine 的初学者,我正在研究我的形成的最终项目。

在这个项目中,我允许用户创建具有与其关联的独特游戏的事件。为此,我有一个与具有 OneToMany 关系的事件实体相关的游戏实体,并且我希望当我删除特定游戏时,与其相关的所有事件都将数据库中的“event_game_id”字段设置为 null。

这是我的代码:

事件实体

<?php

namespace App\Entity;

use App\Repository\EventRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: EventRepository::class)]
#[UniqueEntity('eventName')]
class Event
{
    ...

    #[ORM\ManyToOne(inversedBy: 'events')]
    #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
    private ?Game $eventGame = null;

    ...
}

游戏实体

<?php

namespace App\Entity;

use App\Repository\GameRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: GameRepository::class)]
#[UniqueEntity('gameName')]
class Game
{
    ...

    #[ORM\OneToMany(mappedBy: 'eventGame', targetEntity: Event::class)]
    private Collection $events;

    ...
}

以及用于删除的游戏控制器:

    /**
     * Delete an existing game
     *
     * @param EntityManagerInterface $manager
     * @return Response
     */
    #[Route('/admin/game/delete/{id}', name: 'game.delete', methods: ['GET'])]
    public function delete(EntityManagerInterface $manager, Game $game): Response
    {
        $manager->remove($game);
        $manager->flush();

        return $this->redirectToRoute('game.index');
    }

我已经尝试了多种方法,将 onDelete 选项放在我可以的任何地方,但我总是收到错误:

“执行查询时发生异常:SQLSTATE[23000]:违反完整性约束:1451 无法删除或更新父行:外键约束失败 (

gamesandfriends
.
event
,CONSTRAINT
FK_3BAE0AA761D870AA
FOREIGN KEY (
 event_game_id
)参考文献
game
id
))“

我查看了多个主题和文档,但我肯定错过了一些东西,因为没有任何效果。

提前感谢您的时间和建议!

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

您收到的错误消息意味着您正在尝试删除与其关联的事件的游戏实体。事件表中

event_game_id
列的外键约束阻止您执行此操作。

要解决此问题,您需要将

onDelete
实体中
eventGame
关联上的
Event
选项设置为
SET NULL
。这将告诉 Doctrine 在删除
event_game_id
实体时将事件表中的
NULL
列设置为
Game

这是事件实体的更新代码:

<?php

namespace App\Entity;

use App\Repository\EventRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: EventRepository::class)]
#[UniqueEntity('eventName')]
class Event
{
    ...

    #[ORM\ManyToOne(inversedBy: 'events')]
    #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
    private ?Game $eventGame = null;

    ...
}

更新代码后,您应该能够毫无错误地删除游戏实体。

以下是 onDelete 选项功能的详细说明:

CASCADE
:删除父实体时,删除所有子实体。
SET NULL
:删除父实体时,将子实体中的外键列设置为NULL。
RESTRICT
:如果有任何子实体,则防止父实体被删除。
NO ACTION
:删除父实体时不执行任何操作。 onDelete 选项的默认值为
CASCADE
。但是,在本例中,我们希望在删除
event_game_id
实体时将
NULL
列设置为
Game
,因此我们使用
SET NULL
选项。

© www.soinside.com 2019 - 2024. All rights reserved.