symfony 实体删除和外键约束冲突的问题

9bfwbjaz  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(137)

首先,我对Symfony和Doctrine是一个相当初学者,我正在进行我的形成的最后一个项目。
在这个项目中,我允许用户创建一个唯一的游戏关联到它的事件。要做到这一点,我有一个游戏实体与事件实体一对多的关系,我希望当我删除一个特定的游戏,所有的事件相关的设置字段“事件_游戏_id”在数据库中为空。
下面是我的代码:
事件实体

<?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;

    ...
}

以及用于删除的GameController:

/**
     * 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)REFERENCES gameid))”
我看过多个主题和文件,但我肯定错过了一些东西,因为没有任何工作。
提前感谢您的时间和您的建议!

njthzxwz

njthzxwz1#

您收到的错误消息意味着您正在尝试删除一个与事件关联的游戏实体。事件表中event_game_id列上的外键约束阻止您执行此操作。
要解决这个问题,您需要将Event实体中eventGame关联的onDelete选项设置为SET NULL。这将告诉Doctrine在删除Game实体时将事件表中的event_game_id列设置为NULL
下面是Event实体的更新代码:

<?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。但是,在这种情况下,我们希望在删除Game实体时将event_game_id列设置为NULL,因此我们使用SET NULL选项。

相关问题