首页 > 解决方案 > 为什么 Id AutoGenerated 在 UPDATE with Relation 中使用 Symfony Doctrine 重新生成?

问题描述

Symfony 5.3 学说包 ^2.4 ORM ^2.9 MariaDB 10.6.4

这很难诊断,尤其是当我处理一些复杂的分层代码时。如果我确定的话,我会向 Doctrine 提交一个错误,但我想首先确保我在实施中没有犯一些明显的错误等。

我煞费苦心地尝试将代码简化为简化的工作示例。在我的测试数据库表中,演示代码中没有提到其他列。

// src/Entity/Record.php
declare(strict_types = 1);
namespace App\Entity;

use App\Repository\RecordRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=RecordRepository::class)
 * @ORM\Table(name="Records")
 */
class Record {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    public function getId(): ?int {
        return $this->id;
    }

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\RecordStatus", mappedBy="record", cascade={"persist"})
     * @ORM\JoinColumn(name="Id")
     */
    private ?RecordStatus $recordStatus = NULL;

    public function getRecordStatus(): ?RecordStatus {
        return $this->recordStatus;
    }

    public function setRecordStatus(RecordStatus $value): void {
        $value->setRecord($this);
        $this->recordStatus = $value;
    }
}

// src/Entity/RecordStatus.php
declare(strict_types = 1);
namespace App\Entity;

use App\Repository\RecordStatusRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=RecordStatusRepository::class)
 * @ORM\Table(name="Record_Statuses")
 */
class RecordStatus {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    public function getId(): ?int {
        return $this->id;
    }

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Record", inversedBy="record")
     * @ORM\JoinColumn(name="RecordId")
     */
    private Record $record;

    public function getRecord(): Record {
        return $this->record;
    }

    public function setRecord(Record $value): void {
        $this->record = $value;
    }
}

// src/Controller/DefaultController.php
declare(strict_types = 1);
namespace App\Controller;

use App\Entity\Record;
use App\Entity\RecordStatus;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController {
    /**
     * @Route("/")
     */
    public function home(): Response {
        $doctrine = $this->getDoctrine();
        $entityManager = $doctrine->getManager();
        $recordRepository = $doctrine->getRepository(Record::class);
        $recordStatus = new RecordStatus;
        $item = $recordRepository->find(1);
        $item->setRecordStatus($recordStatus);
        $entityManager->flush();
        return new JsonResponse(['id' => $item->getId()]);
    }
}

当这个路由(“/”)被触发时,更新记录并显示旧的Id。但是在更新之后,检查数据库显示该记录现在有一个新的自动生成 ID,它位于表中最后一条记录之后。请注意,这是在 UPDATE 而不是 INSERT。

我当前的部分解决方法是加载当前映射的关系(如果存在)并更新它而不是使用新的 RecordStatus,但如果需要,也应该可以使用新的相关实例(特别是如果在第一次插入时没有分配关系)。

标签: phpsymfonydoctrine-ormdoctrinemariadb

解决方案


推荐阅读