SQLSTATE[23000]:违反完整性约束:1062 键 'PRIMARY' 的重复条目“60”

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '60' for key 'PRIMARY'

我遇到一个问题,确实,我想要一个函数根据存在与否进行更新或插入。

我在 Symfony 文档中读到: 无论您是创建还是更新对象,工作流程总是相同的:Doctrine 足够聪明,知道它是否应该插入或更新您的实体。

我的存储库:

public function refreshAllArticle()
{
    $articlesActualise = $this->ApiManager->getAllArticles();

    $entityManager = $this->getEntityManager();

    foreach ($articlesActualise as $articleActualise) {


        $article = new Articles();

        $article->setId($articleActualise['id']);

        $article->setDateCreation($articleActualise['date_creation']);
        $article->setDateModification($articleActualise['date_modification']);
        $article->setTitre($articleActualise['titre']);
        $article->setContent($articleActualise['content']);
        $article->setDescription($articleActualise['description']);

        $entityManager->persist($article);

        $entityManager->flush();
    }
}

我的实体:

#[ORM\Entity(repositoryClass: ArticlesRepository::class)]
class Articles
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    private $id;

    #[ORM\Column(type: 'date')]
    private $date_creation;

    #[ORM\Column(type: 'date', nullable: true)]
    private $date_modification;

    #[ORM\Column(type: 'string', length: 255)]
    private $titre;

    #[ORM\Column(type: 'text', nullable: true)]
    private $content;

    #[ORM\Column(type: 'text', nullable: true)]
    private $description;

    #[ORM\Column(type: 'text', nullable: true)]
    private $header;

    #[ORM\Column(type: 'text', nullable: true)]
    private $script;

还有我的控制器:

#[Route('/refreshArticles', name: 'refreshArticles')]
public function refreshArticle(): RedirectResponse
{
    $this->doctrine->getRepository(Articles::class)->refreshAllArticle();
    return $this->redirectToRoute('articles');

}

插入工作完美,但如果我想再次调用此函数进行更新,我会收到此错误: 执行查询时发生异常:SQLSTATE[23000]:违反完整性约束:1062 键 'PRIMARY'

的重复条目“60”

PS : 供参考,我的 ID 不是自动递增的,因为我希望能够插入我自己的值

你能帮我吗谢谢:)

Doctrine 开箱即用地不知道具有给定标识符的实体是否已经存在。它可以确定它应该对一个实体做什么(例如,如果你在同一次执行中坚持两次,它只会插入一次,如果你获取一个实体,更新并坚持它,它将更新实体)。

但是,您目前总是从现有数据中创建 一个新实体并保存它。相反,您应该首先检查具有给定 ID 的实体是否已经存在。我假设这个存储库 class 扩展了 Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository class,它提供了一个“查找”功能来通过 id 获取实体)所以这是一个例子:

public function refreshAllArticle()
{
    $articlesActualise = $this->ApiManager->getAllArticles();

    $entityManager = $this->getEntityManager();

    foreach ($articlesActualise as $articleActualise) {
        // Fetch existing article object
        $articleToUpdate = $this->find($articleActualise['id']);
        if ($articleToUpdate === null) {
            // Article does not exist so we need to create a new object
            $articleToUpdate = new Articles();
        }

        // Update logic goes here using setters on $articleToUpdate 
        // Just like you previously already did

        $entityManager->persist($articleActualise);

        $entityManager->flush();
    }
}

这样您将首先检查该 ID 的实体是否已存在并更新该实体,而不是创建一个新实体。