Symfony Doctrine更新关联关系时主键ID被自动重新生成问题
问题原因
- 关联的所属端(owning side)与反向端(inverse side)配置错误:
Doctrine的一对一关联规则为拥有外键字段的实体为所属端,需配置inversedBy指向反向端的关联属性;反向端需配置mappedBy指向所属端的关联属性,且无需配置@JoinColumn。
你的代码中Record实体的recordStatus属性作为反向端,错误添加了@ORM\JoinColumn(name="Id")配置,指定Record表的主键字段Id为关联RecordStatus的外键,导致Doctrine持久化关联时会直接覆盖Record的主键值,flush时被识别为新实体插入,生成全新自增ID。 - 关联映射属性名匹配错误:
RecordStatus实体的record属性的inversedBy值错误填写为record,但Record中对应的关联属性名为recordStatus,导致关联映射未正常生效。
修复方案
第一步:修正实体关联配置
修改Record实体的关联定义,移除错误的@JoinColumn配置:
// src/Entity/Record.php /** * @ORM\OneToOne(targetEntity="App\Entity\RecordStatus", mappedBy="record", cascade={"persist"}) */ private ?RecordStatus $recordStatus = NULL;
修改RecordStatus实体的关联定义,修正inversedBy值:
// src/Entity/RecordStatus.php /** * @ORM\OneToOne(targetEntity="App\Entity\Record", inversedBy="recordStatus") * @ORM\JoinColumn(name="RecordId", referencedColumnName="id") */ private Record $record;
第二步:适配业务场景优化控制器逻辑
新增关联前先判断是否已有现存关联,没有再新建实例,满足首次绑定和后续更新的需求:
// src/Controller/DefaultController.php public function home(): Response { $doctrine = $this->getDoctrine(); $entityManager = $doctrine->getManager(); $item = $doctrine->getRepository(Record::class)->find(1); // 已有关联则复用,无关联则新建 $recordStatus = $item->getRecordStatus() ?? new RecordStatus(); $item->setRecordStatus($recordStatus); $entityManager->flush(); return new JsonResponse(['id' => $item->getId()]); }
修复后Record的主键不会被关联逻辑覆盖,新建关联时只会在Record_Statuses表插入新行绑定对应RecordId,不会修改原有Record的ID。
内容的提问来源于stack exchange,提问作者dVVIIb
相关产品推荐
相关产品推荐

