API Platform:使用反序列化保存OneToOne关联ID失败求助
问题描述
我尝试为OneToOne关联配置正确的序列化(normalization)和反序列化(denormalization),希望不使用Processor类就能持久化关联列的ID。但通过CompanyLogo实体发起POST请求后,CompanyLogo中的company_id和Company中的company_logo_url_id始终无法保存。附上分组和端点定义,不确定分组配置是否正确,求帮助。
CompanyLogo实体原代码
#[Vich\Uploadable] #[ORM\Entity] #[ApiResource( types: ['https://schema.org/MediaObject'], operations: [ new Post( uriTemplate: '/company/{companyId}/logo', inputFormats: ['multipart' => ['multipart/form-data']], uriVariables: [ 'companyId' => new Link( fromProperty: 'companyLogoUrl', fromClass: Company::class ) ], openapi: new Model\Operation( requestBody: new Model\RequestBody( content: new \ArrayObject([ 'multipart/form-data' => [ 'schema' => [ 'type' => 'object', 'properties' => [ 'file' => [ 'type' => 'string', 'format' => 'binary' ] ] ] ] ]) ) ), ) ], outputFormats: ['jsonld' => ['application/ld+json']], normalizationContext: ['groups' => ['companyLogo:read']], denormalizationContext: ['groups' => ['companyLogo:write']], )] class CompanyLogo { // ... 其他字段 #[ORM\OneToOne(inversedBy: 'companyLogoUrl', targetEntity: Company::class)] #[ORM\JoinColumn(name: 'company_id', referencedColumnName: 'id', unique: true, nullable: false)] #[Groups(['companyLogo:read', 'companyLogo:write'])] private ?Company $company = null; }
Company实体原代码
class Company { #[ORM\OneToOne(mappedBy: 'company', targetEntity: CompanyLogo::class, cascade: ['persist', 'remove'])] #[ORM\JoinColumn(nullable: true)] #[ApiProperty(types: ['https://schema.org/image'])] #[Groups(['company:read', 'company:write'])] public ?CompanyLogo $companyLogoUrl = null; }
解决思路及修正方案
1. 修正URI变量的关联映射
原配置中uriVariables的fromProperty指向错误:Company的companyLogoUrl是mappedBy端(不持有外键),而CompanyLogo的company是inversedBy端(持有外键),正确映射应指向CompanyLogo的company属性,让API平台自动将URI中的companyId绑定到该字段。
2. 同步双向关联的两端
双向OneToOne关联需要手动同步两端的属性,否则仅设置一端无法完成完整的关联绑定,导致外键字段无法持久化。
3. 确保实体具备完整的Setter/Getter方法
原代码中缺少必要的Setter方法,API平台无法正确完成关联对象的赋值操作。
修正后的CompanyLogo实体
#[Vich\Uploadable] #[ORM\Entity] #[ApiResource( types: ['https://schema.org/MediaObject'], operations: [ new Post( uriTemplate: '/company/{companyId}/logo', inputFormats: ['multipart' => ['multipart/form-data']], uriVariables: [ 'companyId' => new Link( fromProperty: 'company', // 修正:指向CompanyLogo的company属性 fromClass: CompanyLogo::class ) ], openapi: new Model\Operation( requestBody: new Model\RequestBody( content: new \ArrayObject([ 'multipart/form-data' => [ 'schema' => [ 'type' => 'object', 'properties' => [ 'file' => [ 'type' => 'string', 'format' => 'binary' ] ] ] ] ]) ) ), ) ], outputFormats: ['jsonld' => ['application/ld+json']], normalizationContext: ['groups' => ['companyLogo:read']], denormalizationContext: ['groups' => ['companyLogo:write']], )] class CompanyLogo { // ... 其他字段 #[ORM\OneToOne(inversedBy: 'companyLogoUrl', targetEntity: Company::class)] #[ORM\JoinColumn(name: 'company_id', referencedColumnName: 'id', unique: true, nullable: false)] #[Groups(['companyLogo:read', 'companyLogo:write'])] private ?Company $company = null; // 修正setCompany方法,同步双向关联 public function setCompany(?Company $company): self { $this->company = $company; // 同步Company端的关联,避免循环调用 if ($company !== null && $company->getCompanyLogoUrl() !== $this) { $company->setCompanyLogoUrl($this); } return $this; } public function getCompany(): ?Company { return $this->company; } // ... VichUploadable相关的文件处理方法(需确保存在) }
修正后的Company实体
class Company { #[ORM\OneToOne(mappedBy: 'company', targetEntity: CompanyLogo::class, cascade: ['persist', 'remove'])] #[ORM\JoinColumn(nullable: true)] #[ApiProperty(types: ['https://schema.org/image'])] #[Groups(['company:read', 'company:write'])] public ?CompanyLogo $companyLogoUrl = null; // 新增setter方法,同步双向关联 public function setCompanyLogoUrl(?CompanyLogo $companyLogoUrl): self { $this->companyLogoUrl = $companyLogoUrl; // 避免循环调用,仅当对方未绑定当前实例时同步 if ($companyLogoUrl !== null && $companyLogoUrl->getCompany() !== $this) { $companyLogoUrl->setCompany($this); } return $this; } public function getCompanyLogoUrl(): ?CompanyLogo { return $this->companyLogoUrl; } }
内容的提问来源于stack exchange,提问作者Filip Stojanovic
相关产品推荐
相关产品推荐

