Home > OS >  Doctrine : need to call set or add in many to one relation?
Doctrine : need to call set or add in many to one relation?

Time:10-14

This is more a question than a problem. I have 2 entities related by a Many To One relation :

class TestScore {
[...]
    /**
     * @ORM\ManyToOne(targetEntity="Modules\TestBundle\Entity\TestUser" , cascade={"persist"}, inversedBy="scores")
     * @ORM\JoinColumn(name="test_user_id", onDelete="CASCADE")
     */
    private $testUser;
[...]
}

class TestUser {
[...]
/**
 * @ORM\OneToMany(targetEntity="Modules\TestBundle\Entity\TestScore" , cascade={"persist"}, mappedBy="testUser")
 */
private $scores;
[...]
}

and in a service, I've got something like :

    public function createScore(TestUser $testUser, string $code, $score, string $description = null) {
            $testScore = new TestScore();
            $testScore->setTestUser($testUser);
            $testScore->setCode($code);
            $testScore->setScore($score);
            $testScore->setDescription($description);
    
            $this->em->persist($testScore);
        }

In this case, if I make something like :

$scoringService->createScore($testUser, 'total', $totalActivity);
dump($em->getRepository(TestScore::class)->findBy('testUser' => $testUser));
dump($testUser->getScores());

My 1st dump return 1 TestScore with right datas and my 2nd return null !

But if I add

$testUser->addScores($testScore);

to $scoringService->createScore(), my 2nd dump return the right datas.

I thought doctrine automaticaly add score to testUser while $testScore->setTestUser($testUser);

can someone confirm it to me ? Thanks !!

CodePudding user response:

Doctrine automatically creates/populates the connection from both sides when that kind of data is loaded from the database (i.e. if you would load the user again at some other point it would have the testScore instances linked).

But when you initially create the entities and set the references, you will need to do the set/add on both sides if you want to use the references right away with the same object. A fairly standard solution for this (used by the symfony entity generator for example) is that both sides of the references are set in the oneToMany side add method like:

public function addScores(TestScore $testScore): self
{
    if (!$this->testScores->contains($testScore)) {
        $this->testScores[] = $testScore;
        $testScore->setTestUser($this);
    }

    return $this;
}

and with that you will need to call only the addScores from your service and let the entity code fill in the other side of the connection for the current instances.

  • Related