API 平台:规范化映射超类仅包括来自超类的属性,不包括子类

Posted

技术标签:

【中文标题】API 平台:规范化映射超类仅包括来自超类的属性,不包括子类【英文标题】:API Platform: Normalizing a Mapped Superclass only includes properties from the superclass, not the child class 【发布时间】:2020-12-22 02:31:08 【问题描述】:

编辑:创建了一个包含简单用例的存储库来复制问题,并在 API 平台问题队列中创建了一个问题,地址为 https://github.com/api-platform/api-platform/issues/1648。

我有一个SurveyData 映射的超类,它有多个实现它的子类。对于这个问题,MonthlyDataSurveyData 超类的子类。

我有一个Submission API 资源,它与SurveyDataOneToOne 关系。

当我检索它时,我正在尝试将SurveyData 子实体(在本例中为MonthlyData 实体)内联到我的提交实体中。我在SubmissionApiResource 注释中设置了normalizationContext,并在我想要内联的各种属性上设置了@Groups 注释。

除了@id@type JSON-LD 属性之外,我的SurveyData 映射超类的属性内联显示在我的Submission 实体中。 但是,实际子实体 (MonthlyTotals) 的属性不会出现。

我可以确认传递给规范化器的对象是一个完全填充的MonthlyTotals 对象,但规范化器的输出仅包含在SurveyData 映射超类中定义的属性。

我可以确认我正在使用默认的核心 API 平台 JSON-LD 规范化器。

提前感谢您的帮助!

这是一个Submission 定义(为简洁起见,减去'use'语句和getter / setter:

<?php
/**
 * @ApiResource(
 *   normalizationContext="groups"="submission",
 *   denormalizationContext="groups"="submission",
 *   itemOperations=
 *     "get"=
 *       "method"="GET",
 *       "access_control"="is_granted('view', object)",
 *     ,
 *     "put", "patch", "delete",
 *   ,
 * )
 *
 * @ApiFilter(NumericFilter::class, properties="patient.id")
 * @ApiFilter(OrderFilter::class, properties="created", "status", "patient.chartID", arguments="orderParameterName"="order")
 * @ApiFilter(SearchFilter::class, properties="status": "exact", "patient.chartID": "exact")
 * @ORM\Entity(repositoryClass="App\Repository\SubmissionRepository")
 * @DelphiAssert\SubmissionDataIsValid
 */
class Submission

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups("submission")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Facility")
     * @ORM\JoinColumn(nullable=false)
     * @Groups("submission")
     */
    private $facility;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Patient", inversedBy="submissions")
     * @Groups("submission")
     */
    private $patient;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups("submission")
     */
    private $survey;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Groups("submission")
     */
    private $dateDetail;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\Type("\DateTimeInterface")
     * @Groups("submission")
     */
    private $created;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\Type("\DateTimeInterface")
     * @Groups("submission")
     */
    private $updated;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups("submission")
     */
    private $user;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups("submission")
     */
    private $status;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\SurveyData\SurveyData", inversedBy="submission", cascade="persist", "remove", orphanRemoval=true, fetch="EAGER")
     * @Groups("submission")
     */
    private $surveyData;

这里是 SurveyData(条件相同):

<?php
/**
 * @ORM\Entity(repositoryClass="App\Repository\SurveyData\SurveyDataRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap(
 *   "SurveyData" = "App\Entity\SurveyData\SurveyData",
 *   "RPCSEducationProcessMeasures" = "App\Entity\SurveyData\RPCS\EducationProcessMeasures",
 *   "RPCSMonthlyTotals" = "App\Entity\SurveyData\RPCS\MonthlyTotals"
 * )
 */
class SurveyData

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups("submission")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Submission", mappedBy="surveyData", cascade="persist", "remove", fetch="EAGER")
     */
    private $submission;

这里是每月数据:

/**
 * @ApiResource(
 *   normalizationContext="groups"="submission",
 *   denormalizationContext="groups"="submission"
 * )
 * @ORM\Entity(repositoryClass="App\Repository\SurveyData\RPCS\MonthlyTotalsRepository")
 */
class MonthlyTotals extends SurveyData


    /**
     * @ORM\Column(type="integer")
     * @Groups("submission")
     */
    private $num_deliveries;

    /**
     * @ORM\Column(type="integer")
     * @Groups("submission")
     */
    private $num_cesarean;

    /**
     * @ORM\Column(type="integer")
     * @Groups("submission")
     */
    private $num_epidural_anesthesia;

【问题讨论】:

看起来像序列化程序组问题。你能显示相关实体的代码吗? 嗨@shvv。为简洁起见,我添加了实体定义减去 use 语句和 getter / setter。成为序列化程序组问题似乎是合理的,但我已经多次阅读该文档但没有解决。 @BrianV 你能添加序列化器的代码吗?我尝试设置一个测试用例并重现您的问题。 floGalen:我实际上已经在 repo 中构建了一个复制用例,并在 github.com/api-platform/api-platform/issues/1648 上为它创建了一个 Github 问题 【参考方案1】:

可能是@Groups("submission") v. @Groups("submission")。 全部改成@Groups("submission")

很难用当前的文档来验证,因为它现在是用 PHP8 属性记录的。我只使用了 YAML 配置,所以不能 100% 确定。

【讨论】:

以上是关于API 平台:规范化映射超类仅包括来自超类的属性,不包括子类的主要内容,如果未能解决你的问题,请参考以下文章

休眠:覆盖(实体)超类的 OneToMany 映射字段?

如何访问 Python 超类的属性,例如通过 __class__.__dict__?

Jackson 序列化:如何忽略超类属性

Java中类的继承

子类会在后台包含来自超类的私有方法和成员变量吗? [复制]

Java超类-java.lang.object