0

I am trying to build an Api with Symfony and Api Platform. Unfortunately one of the fields I created in the Entity class does not appear in the schema. It is an Many To One relation. I rebuilt this Api from an yt tutorial and can't find the mistake.

I tried to Change the name of the Producer Entity. When I changed it to 'Manufacturer' the Product-Schema was correct but the Manufacturer-Schema wasn't anymore. When I change it to 'Producer' the Product-Schema isn't complete but the Manufacturer-Schema is correct.

-> Producer Entity

<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/** A Producer. */
#[ORM\Entity]
#[ApiResource]
class Producer
{
    /** The ID of the producer */
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    /** The title of the producer */
    #[ORM\Column]
    private string $title = '';

    /** The description of the producer */
    #[ORM\Column(type: 'text')]
    private string $description = '';

    /** The country code of the producer */
    #[ORM\Column(length: 3)]
    private string $countryCode = '';

    /** the date that the producer was listed */
    #[ORM\Column(type: 'datetime')]
    private ?\DateTimeInterface $listedDate = null;


    /**
     * @var Product[] Available products from this producer
     */
    #[ORM\OneToMany(mappedBy: "producer", targetEntity: "App\Entity\Product", cascade: ["persist", "remove"])]
    private iterable $products;


    public function __construct()
    {
        $this->products = new ArrayCollection();
    }

    public function getTitle(): string{
        return $this->title;
    }

    public function setTitle(string $title): void{
        $this->title = $title;
    }

    /**
     * Get the value of id
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * Set the value of id
     *
     * @param $id
     * @return  self
     */
    public function setId($id): static
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get the value of description
     */
    public function getDescription(): string
    {
        return $this->description;
    }

    /**
     * Set the value of description
     *
     * @param $description
     * @return  self
     */
    public function setDescription($description): static
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get the value of countryCode
     */
    public function getCountryCode(): string
    {
        return $this->countryCode;
    }

    /**
     * Set the value of countryCode
     *
     * @param $countryCode
     * @return  self
     */
    public function setCountryCode($countryCode): static
    {
        $this->countryCode = $countryCode;

        return $this;
    }

    /**
     * Get the value of listedDate
     */
    public function getListedDate(): ?\DateTimeInterface
    {
        return $this->listedDate;
    }

    /**
     * Set the value of listedDate
     *
     * @param $listedDate
     * @return  self
     */
    public function setListedDate($listedDate): static
    {
        $this->listedDate = $listedDate;

        return $this;
    }

    /**
     * Get the value of products
     */
    public function getProducts(): iterable|ArrayCollection
    {
        return $this->products;
    }
}

-> Product Entity

<?php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;

/**
 * A Product
 */
#[ORM\Entity]
#[ApiResource]
class Product
{
    /** The id of the product */
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    /** the MPN of the product */
    #[ORM\Column]
    private ?string $mpn = null;

    /** The name of the product */
    #[ORM\Column]
    private string $name = '';

    /** The description of the product */
    #[ORM\Column(type: 'text')]
    private string $description = '';

    /** The date of issue of the product */
    #[ORM\Column(type: 'datetime')]
    private ?\DateTimeInterface $issueDate = null;

    /**
     * The producer of the product.
     *
     */
    #[ORM\ManyToOne(targetEntity: 'App\Entity\Producer', inversedBy: 'products')]
    private ?Producer $producer = null;

    

    /**
     * Get the value of id
     */ 
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * Get the value of mpn
     */ 
    public function getMpn(): ?string
    {
        return $this->mpn;
    }

    /**
     * Set the value of mpn
     *
     * @return  self
     */ 
    public function setMpn($mpn): static
    {
        $this->mpn = $mpn;

        return $this;
    }

    /**
     * Get the value of name
     */ 
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Set the value of name
     *
     * @return  self
     */ 
    public function setName($name): static
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get the value of description
     */ 
    public function getDescription(): string
    {
        return $this->description;
    }

    /**
     * Set the value of description
     *
     * @return  self
     */ 
    public function setDescription($description): static
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get the value of issueDate
     */ 
    public function getIssueDate(): ?\DateTimeInterface
    {
        return $this->issueDate;
    }

    /**
     * Set the value of issueDate
     *
     * @return  self
     */ 
    public function setIssueDate($issueDate): static
    {
        $this->issueDate = $issueDate;

        return $this;
    }

    /**
     * @return Producer|null
     */
    public function getProducer(): ?Producer
    {
        return $this->producer;
    }

    /**
     * @param Producer|null $producer
     */
    public function setProducer(?Producer $producer): void
    {
        $this->producer = $producer;
    }
}
Brentspine
  • 274
  • 1
  • 15
Kocher
  • 23
  • 1
  • 1
  • 5
  • Did you try to fetch with eager loading, I think by default it fetches as 'LAZY'. you can try {fetch = "EAGER"} You can check out this link: https://stackoverflow.com/questions/26891658/what-is-the-difference-between-fetch-eager-and-fetch-lazy-in-doctrine – Vaso Gamdelidze Jul 23 '23 at 19:30
  • "I rebuilt this Api from an yt tutorial" - Did you use Doctrine to build these objects? If yes I would try to delete the Entities and Repositories and reconstruct them. – Brentspine Jul 24 '23 at 20:37
  • @Brentspine you mean I should basically let Doctrine recreate the database or did I misunderstand that? – Kocher Jul 28 '23 at 19:28

1 Answers1

0

After manually changing Repositories or Entities in the src directory you need to make sure the changes are:

  1. Compatible with the other Entities, e.g. if you change field names you have to change dependend attributes in other classes. You can check this quickly by using php bin/console doctrine:schema:validate, which checks your files for any schema errors.

  2. Migrated to the database, you can achieve this with the following commands: php bin/console make:migration, which creates the migration files in /migrations and php bin/console doctrine:migration:migrate, which executes these migrations.

I advise you to change the targetEntity attributes from string to Entity::class type, meaning you change lines like

#[ORM\ManyToOne(targetEntity: 'App\Entity\Producer', inversedBy: 'products')]

to

#[ORM\ManyToOne(targetEntity: Producer::class, inversedBy: 'products')]

This makes it easier for your IDE to refractor name changes and will probably solve the source of your problem

Brentspine
  • 274
  • 1
  • 15