DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Doctrine JOINED 继承迁移把子表外键指错,核对延后提交的关联外键

Doctrine JOINED 关联标识的子表外键曾被待添加队列中的同名定义覆盖。3.7.4 包含修补,已执行的错误约束仍需要审阅后迁移修复。

Doctrine ORM 的 JOINED 继承模型升级后,子表的外键突然指向标识关联的目标表,而不是继承根表,要检查 schema 生成阶段的待添加外键队列。模型查询看起来正常,也不能证明生成的数据库约束正确。

具体组合是:根实体采用 JOINED 继承,标识列同时是 OneToOne 或 ManyToOne 关联,子实体继承该标识。子表的同名标识列需要连接根表;根表再通过自己的关联连接目标表。3.7.0 至 3.7.3 的故障案例中,后续待添加的关联外键覆盖了子表已经建立的继承外键。

外键名称根据表与列生成,两份定义使用相同子表列名,就可能占据同一个名字。问题不是数据库随意选错约束,而是生成器晚加入的一份定义把前一份正确定义替换了。仅改外键名字让两份都保留下来,也不符合这个继承结构应有的约束。

Doctrine ORM 3.7.4 包含对应修补:给子表建立必要的根表外键前,从待添加队列移除该表及继承键列对应的错误关联条目。传统和实验性 schema 路径都有相应处理。它没有删除根实体真正需要的关联外键,也不是取消所有 JOINED 约束。

更新依赖后,先生成并审阅迁移差异:

composer update doctrine/orm --with-all-dependencies
composer show doctrine/orm

使用项目既有的迁移生成命令,检查子表外键的目标表、列和删除规则。应看到子表标识连接根表,而根表关联仍连接原目标表。如果先前已执行错误迁移,升级 PHP 包不会自动修改数据库,需要生成并审阅单独的约束修复迁移。

验收可以从 ORM 生成的 Schema 对象中找到子表,读取 getForeignKeys(),断言继承标识列只对应预期的根表外键,再检查实际数据库约束。然后在隔离数据上验证插入父子记录、删除和级联行为,尤其是项目真实使用的删除规则。不要只用一条查询成功判断约束已经修复。

此边界针对 JOINED 根实体的关联标识及子表外键覆盖。普通单表继承、标量标识、运行期集合合并遗漏,或者业务自己定义了错误外键,都不是同一原因。若生成 SQL 仍有差异,先保留完整 metadata 与迁移片段再定位,不要全局禁用外键约束。