0
votes

In Symfony 5, I've created 2 entities related with a ManyToOne relation : Project is the parent, Serie is the child.

Project entity :

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\SerieRepository")
 */
class Serie
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Project", inversedBy="series")
     * @ORM\JoinColumn(nullable=false)
     */
    private $project;

    [...]
}

Serie entity :

namespace App\Entity;


use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProjectRepository")
 */
class Project
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;


    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Serie", mappedBy="Project", orphanRemoval=true)
     */
    private $series;

    [...]
}

I didn't write down here, but you also have all the getter and setter for each class.

I need to access to the Project entity in the Serie entity. For example : accessing to the name property of Project entity by adding a getProjectName method in Serie class.

    public function getProjectName()
    {
        return $this->project->getName();
    }

But this is not working as the Project entity is not loaded (only the id). How can I get this value, without adding a repository in the entity class or passing any argument to the getProjectName method ? (maybe a Doctrine annotation...).

2

2 Answers

1
votes

In doctrine entities in relations are lazy-loaded, that means, when you have not accessed anything on $this->project (or the referenced project), it will just be of type Project^ (notice the ^) and it will have an attribute called __initialized__ (or similar) with the value false (check by dump($this->project);). This means, that the entity is NOT loaded, yet.

Lazy-loading means, it will be loaded if it's actually needed (thus reducing database accesses), and before that, a proxy object will take the place of the entity. It'll register all calls done to it, load the entity if necessary and forward all calls to it.

So, to load a lazy-loaded entity, you just call one of its methods. So $this->project->getName() should already work nicely. (verify by calling dump($this->project); afterwards).

If it doesn't, something else is missing/wrong/dysfunctional.

0
votes

Ok, thank you Jakumi. You are right, on that way, it's working fine.

To complete your explanation, if you want to get the child elements, like :

$series = $project->getSeries();

You will have an empty table (a foreach loop won't get any item). This is because $series is a Doctrine Collection. You need to use :

$series = $project->getSeries()->getValues();

to have a fully completed array.

I spend 2 hours on the topic, I hope this will help somebody else.