php - symfony 学说鉴别器错误序列化器
问题描述
我使用一个平台开发rest API,现在当我在 normalize 和 denormalize 中序列化数据时,我发现了一个错误。我对实体使用学说继承,我有类人抽象类内容公共属性,我创建类合作伙伴,参与者和声明者,所有类都为人员类扩展,现在当我在参与者类中添加组时发现错误,错误是我在显示的合作伙伴和声明属性中添加了一个组,但是当我在属性类 Person 中添加一个组时,不显示类 Participant 中的属性
个人实体:
<?php
namespace App\Entity;
use App\Repository\PersonRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(repositoryClass=PersonRepository::class)
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"partner" = "Partner", "supplier" = "Supplier", "declaring"= "Declaring", "particpant"= "Particpant"})
*/
abstract class Person
{
use ResourceId;
use AbstractEntity;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"readPartner","writePartner","readDeclaring",
* "writeDeclaring","readSupplier","writeSupplier","readParticpant","writeParticpant"})
*/
private $firstName;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"readPartner","writePartner","readDeclaring",
* "writeDeclaring","readSupplier","writeSupplier","readParticpant","writeParticpant"})
*/
private $lastName;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"readPartner","writePartner","readDeclaring",
* "writeDeclaring","readSupplier","writeSupplier"})
*/
private $personalPhone;
/**
* @ORM\Column(type="string", length=255,nullable=true)
* @Groups({"readPartner","writePartner","readDeclaring"
* ,"writeDeclaring","readSupplier","writeSupplier"})
*/
private $professionalPhone;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\Email(
* message = "The email '{{ value }}' is not a valid email."
* )
* @Groups({"readPartner","writePartner","readDeclaring",
* "writeDeclaring","readSupplier","writeSupplier"})
*/
private $email;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"readPartner","writePartner","readDeclaring"
* ,"writeDeclaring","readSupplier","writeSupplier"})
*/
private $organization;
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getPersonalPhone(): ?string
{
return $this->personalPhone;
}
public function setPersonalPhone(string $personalPhone): self
{
$this->personalPhone = $personalPhone;
return $this;
}
public function getProfessionalPhone(): ?string
{
return $this->professionalPhone;
}
public function setProfessionalPhone(string $professionalPhone): self
{
$this->professionalPhone = $professionalPhone;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getOrganization(): ?string
{
return $this->organization;
}
public function setOrganization(string $organization): self
{
$this->organization = $organization;
return $this;
}
}
参与实体:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\ParticpantRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* normalizationContext={"groups"={"readParticpant"}},
* denormalizationContext={"groups"={"writeParticpant"}},
* )
* @ORM\Entity(repositoryClass=ParticpantRepository::class)
*/
class Particpant extends Person
{
/**
* @ORM\ManyToOne(targetEntity=Partner::class)
* @ORM\JoinColumn(name="partner_id", referencedColumnName="id", nullable=true)
* @Groups({"readParticpant","writeParticpant"})
*/
protected $partner;
/**
* @ORM\ManyToOne(targetEntity=Declaring::class)
* @ORM\JoinColumn(name="declaring_id", referencedColumnName="id", nullable=true)
* @Groups({"readParticpant","writeParticpant"})
*/
protected $declaring;
/**
* Get the value of partner
*/
public function getPartner(): ?Partner
{
return $this->partner;
}
/**
* Set the value of partner
* @param Partner $partner
* @return self
*/
public function setPartner(Partner $partner): self
{
$this->partner = $partner;
return $this;
}
/**
* Get the value of declaring
*/
public function getDeclaring(): ?Declaring
{
return $this->declaring;
}
/**
* Set the value of declaring
* @param Declaring $declaring
* @return self
*/
public function setDeclaring(Declaring $declaring): self
{
$this->declaring = $declaring;
return $this;
}
}
如何显示人员实体的属性和参与者的属性也..
解决方案
即使学说很好地支持继承,api-platform 也不支持。
反序列化忽略父类属性或子类属性。
真正的问题是为什么需要继承?
- 添加一个新的实体类链接到 Person ?
- 使用多态性,比如
public function heal(Person $person): void {}
? - 收集共同属性?
如果是1.,那你就完蛋了。例如,假设您要添加一个Dog类:
/*
* @ApiResource
* @ORM\Entity
*/
class Dog
{
/*
* @Column
*/
private $name;
/*
* @var Person
* @ManyToOne(class="Person")
*/
private $owner;
}
即使使用具体的Person类,序列化也不会按预期工作,IRI 生成不会检测到子类。你不会看到像这样的几个Dog实例:
{"name": "Bar", "owner": "/participants/1"}
{"name": "Foo", "owner": "/partners/2"}
{"name": "Dummy", "owner": "/declarants/4"}
Api-platform 将尝试创建包含/persons字符串的 IRI。获取/persons仅检索 Person 属性。
如果是2.,您的实体只需要实现一个通用接口,或者您可以使用访问者模式。
如果是3.,常用的方法是使用学说embeddable objects。它们支持@Groups注释。
推荐阅读
- linux - 如何从 grep 输出中提取特定的键值对
- python - Selenium Select 在找到一个元素后返回 None
- javascript - 使用 fetch 获取页面设置
- python - 如何重塑多索引数据框?
- node.js - 在这段代码中,为什么要在发布之前执行,为什么我必须在下拉列表中选择 2 个值才能将其存储到变量中?
- c++ - 为什么我不能在 x64 项目中嵌入 lua?
- wordpress - 重写规则在子主题 wordpress 中不起作用
- java - JavaFX 绝对位置布局,但允许一些孩子与父母一起成长
- mysql - 非选择查询的自定义函数 Cake Query Builder
- ios - 在终端中尝试“xcodebuild 存档”时存档失败