Tuesday, 8 September 2020

API Platform: Normalizing a Mapped Superclass only includes properties from the superclass, not the child class

I have a SurveyData mapped superclass, which has multiple child classes that implement it. For this question, MonthlyData is a child of the SurveyData superclass.

I have a Submission API resource that has a OneToOne relationship to a SurveyData.

I am trying to normalize the SurveyData child entity (in this case, a MonthlyData entity) inline into my Submission entity when I retrieve it. I've set the normalizationContext in my Submission's ApiResource annotation, and set the @Groups annotations on the various properties I want to have inline.

It's mostly working, in that the properties of my SurveyData mapped superclass appear inline in my Submission entity, in addition to the @id and @type JSON-LD properties. However, properties from the actual child entity (MonthlyTotals) do not appear.

I can confirm that the object being passed into the normalizer is a fully populated MonthlyTotals object, but the output of the normalizer only contains the properties defined in the SurveyData mapped superclass.

I can confirm I am using the default core API platform JSON-LD normalizer.

Thank you in advance for any help!

Here is a Submission definition (minus 'use' statements and getters / setters for brevity:

<?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;

Here's SurveyData (same conditions):

<?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;

and here's MonthlyData:

/**
 * @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;


from API Platform: Normalizing a Mapped Superclass only includes properties from the superclass, not the child class

No comments:

Post a Comment