Reputation: 1
I'm working with API Platform using Doctrine Inheritance and I have a problem persisting a OneToMany relation.
curl --location 'http://localhost/api/dummies' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"fakeField": "string",
"metadata": [
{
"name": "string",
"value": "string"
}
]
}'
The response return the metadata as empty array and the objects was not persisted on the table.
{
"id": "21f2051e-4dbe-4992-976d-ba3421c6aece",
"fakeField": "string",
"metadata": []
}
The entities definitions:
// ./src/Entity/AbstractMetadataAwareEntity.php
#[ORM\Entity]
#[ORM\Table(name: 'an_objects')]
#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'entity_type', type: 'string')]
#[ORM\DiscriminatorMap([
'user' => User::class,
'dummy' => Dummy::class,
])]
class AbstractMetadataAwareEntity
{
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
#[ORM\Column(type: 'uuid', unique: true)]
#[Groups(['base:read'])]
protected UuidV6 $id;
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Metadata::class, cascade: ['persist'])]
#[Groups(['base:read', 'base:write'])]
protected Collection $metadata;
public function __construct()
{
$this->metadata = new ArrayCollection();
}
public function getId(): UuidV6
{
return $this->id;
}
/**
* @return Collection<int, Metadata>
*/
public function getMetadata(): Collection
{
return $this->metadata;
}
public function addMetadata(Metadata $metadata): self
{
if (!$this->metadata->contains($metadata)) {
$this->metadata->add($metadata);
$metadata->setOwner($this);
}
return $this;
}
public function removeMetadata(Metadata $metadata): self
{
if ($this->metadata->removeElement($metadata)) {
// set the owning side to null (unless already changed)
if ($metadata->getOwner() === $this) {
$metadata->setOwner(null);
}
}
return $this;
}
}
// ./src/Entity/Dummy.php
#[ORM\Entity(repositoryClass: DummyRepository::class)]
#[ApiResource(
normalizationContext: [
'groups' => ['base:read', 'dummy:read']
],
denormalizationContext: [
'groups' => ['base:write', 'dummy:write']
]
)]
class Dummy extends AbstractMetadataAwareEntity
{
#[ORM\Column(length: 255)]
#[Groups(['dummy:read', 'dummy:write'])]
private ?string $fakeField = null;
public function getFakeField(): ?string
{
return $this->fakeField;
}
public function setFakeField(string $fakeField): self
{
$this->fakeField = $fakeField;
return $this;
}
}
// ./src/Entity/Metadata.php
#[ORM\Entity(repositoryClass: MetadataRepository::class)]
#[ORM\Table(name: 'an_metadatas')]
class Metadata
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write'])]
private ?string $name = null;
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write'])]
private ?string $value = null;
#[ORM\ManyToOne(inversedBy: 'metadata')]
#[ORM\JoinColumn(nullable: false)]
private ?AbstractMetadataAwareEntity $owner = null;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getValue(): ?string
{
return $this->value;
}
public function setValue(string $value): self
{
$this->value = $value;
return $this;
}
public function getOwner(): ?AbstractMetadataAwareEntity
{
return $this->owner;
}
public function setOwner(?AbstractMetadataAwareEntity $owner): self
{
$this->owner = $owner;
return $this;
}
}
This implementation use Doctrine Inheritance
The expected result is the correct persistance for User and Metadata objects into their respective tables
Upvotes: 0
Views: 508
Reputation: 10897
Given the following from Dummy
:
#[Groups(['dummy:read', 'dummy:write'])]
private ?string $fakeField = null;
And the fact that the response is showing "fakeField"
I deduce that you have the group 'dummy:read'
or 'dummy:write'
however the collection items do not use either of those groups:
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write'])]
private ?string $name = null;
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write'])]
private ?string $value = null;
So there are no property values to include in the serialized data.
Try adding the 'dummy:*'
groups to each field you want returned.
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write', 'dummy:read', 'dummy:write'])]
private ?string $name = null;
#[ORM\Column(length: 255)]
#[Groups(['base:read', 'base:write', 'dummy:read', 'dummy:write'])]
private ?string $value = null;
Sorry, I'm not an API Platform guy.
Upvotes: 0