Doctrine实体二级继承场景下API Platform使用异常问题咨询
问题原因与修复方案
1. Doctrine 继承配置错误
你当前的配置不符合Doctrine JOINED继承的规范:
- 多级JOINED继承体系中,仅根类(MyParent)需要配置
@InheritanceType、@DiscriminatorColumn、@DiscriminatorMap注解,子类重复配置该类注解会导致映射逻辑异常 - 根类的
@DiscriminatorMap需要列出继承树中所有的类(包括根类本身、所有直接/间接子类),你当前仅配置了MyChild,缺少MyChildChild的映射 - MyChild表没有discr列属于正常现象:JOINED继承的鉴别器字段仅会保存在根类对应表中,所有子类的实例类型统一通过根表的discr字段判断,不需要子类表重复存储该字段
2. API Platform报错原因
报错本质是Doctrine实体映射配置错误导致元数据解析异常,并非API Platform本身的问题,修复Doctrine配置后即可正常运行。
修正后代码
MyParent.php
// src/Entity/MyParent.php namespace App\Entity; use ApiPlatform\Core\Annotation\ApiResource; use App\Repository\MyParentRepository; use Doctrine\ORM\Mapping as ORM; /** * @ApiResource() * @ORM\Entity(repositoryClass=MyParentRepository::class) * @ORM\InheritanceType("JOINED") * @ORM\DiscriminatorColumn(name="discr", type="string") * @ORM\DiscriminatorMap({ * "parent" = "MyParent", * "child" = "MyChild", * "childchild" = "MyChildChild" * }) */ class MyParent { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=255) */ private $parentAttribute; public function getId(): ?int { return $this->id; } public function getParentAttribute(): ?string { return $this->parentAttribute; } public function setParentAttribute(string $parentAttribute): self { $this->parentAttribute = $parentAttribute; return $this; } }
MyChild.php
// src/Entity/MyChild.php namespace App\Entity; use ApiPlatform\Core\Annotation\ApiResource; use App\Repository\MyChildRepository; use Doctrine\ORM\Mapping as ORM; /** * @ApiResource() * @ORM\Entity(repositoryClass=MyChildRepository::class) */ class MyChild extends MyParent { /** * @ORM\Column(type="string", length=255) */ private $childAttribute; public function getChildAttribute(): ?string { return $this->childAttribute; } public function setChildAttribute(string $childAttribute): self { $this->childAttribute = $childAttribute; return $this; } }
MyChildChild.php 无需修改
后续操作
修改完成后执行命令更新数据库结构即可:php bin/console doctrine:schema:update --force
如果不需要将MyChild、MyChildChild单独暴露为API资源,可删除对应类上的@ApiResource注解,避免生成多余接口。
内容的提问来源于stack exchange,提问作者Hervé LE BARS
相关产品推荐
相关产品推荐

