php - Why doesn't the ids of an Entity start incrementing at 1 during Fixtures loading?

664

I've made Fixtures for two of my entities that have a ManyToMany relation. MyColorFixtures load, then myFabricFixtures. As you can see in code below, I add a color to my fabric by using theColorRepository. I always get following error :

Argument 1 passed to App\Entity\Fabric::addColor() must be an instance of App\Entity\Color, null given, called in /var/www/html/src/DataFixtures/FabricFixtures.php on line 44

So I tried to dig a little deeper, and the thing is, at the end of the loading of ColorFixtures, the ids of my colors go from 222 to 241 (since I've tried a lot of times to load these fixtures, at one point the ids must have been lower numbers, because the next loading I dumped, the ids where from 242 to 261, and I tried a unique one before that was 221).

So of course when I use the ColorRepository to find id 1 to 20 in the FabricFixtures, the color is null because at that point the ids are 200 times higher.

When I dump the colors after the Fixtures process (in a Controller), the ids are correctly set from 1 to 20. Thus my question : Why doesn't the ids of an Entity start incrementing at 1 during Fixtures loading? I guess there's some cache of previous loadings of Fixtures, but I don't really know, and if that's indeed the case, why there's even a cache. How could I make sure that the ids always start incrementing at 1 so that I can safely add colors to my fabrics?

Note: even after runningbin/console cache:clear, the "temporary" ids are still increasing (last time I dumped: 282 to 301).

Note 2: I don't know if that matters, but I'm using Symfony 5, and doctrine/doctrine-fixtures-bundle 3.3

Note 3: I think this is a related issue and I understand after reading the maintainer's answer that I shouldn't depend on the incremented ids of my Entity in the Fixtures of another. Do I understand well? If so, do you have any lead on how I could do to create the relationship between the fabric and the color?

Note 4: Actually, this is a personal project I've been working on for a few months now, aside from work & school, and I had first started developping it with Laravel, then I did it with Symfony to learn the framework, then back to Laravel because I preferred this framework, and now I'm back again (and finally !) on Symfony. And in the Laravel version I just made a FabricColor "Fixtures" where I made DB queries to add the raw ids to the DB table. Is that how I should do it in Symfony to? In the end, shouldn't my question be: What is the best way to make Fixtures with ManyToMany relations?"

Thanks a lot!

FabricFixtures
(I use the  ̀DependentFixtureInterface` to be sure the ColorFixtures effectively load before the FabricFixtures)

<?php

namespace App\DataFixtures;

use App\Entity\Fabric;
use App\Repository\ColorRepository;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Factory;

class FabricFixtures extends Fixture implements DependentFixtureInterface
{
    /** @var ColorRepository */
    private $colorRepository;

    /**
     * FabricFixtures constructor.
     * @param ColorRepository $colorRepository
     */
    public function __construct(ColorRepository $colorRepository)
    {
        $this->colorRepository = $colorRepository;
    }

    /**
     * @param ObjectManager $manager
     */
    public function load(ObjectManager $manager)
    {
        $faker = Factory::create();

        for ($i = 0; $i < 30; $i++) {
            $fabric = new Fabric();
            $fabric->setBox(rand(1, 30));
            $fabric->setMaterial($faker->word);
            $fabric->setPattern($faker->word);
            $fabric->setState($faker->word);
            $fabric->setThickness($faker->word);
            $fabric->setWidth(rand(100, 500));
            $fabric->setLength(rand(100, 500));
            $fabric->setComment($faker->words(5, true));
            $fabric->addColor($this->colorRepository->find(rand(1, 20)));

            $manager->persist($fabric);
        }

        $manager->flush();
    }

    /**
     * @inheritDoc
     */
    public function getDependencies()
    {
        return [
            ColorFixtures::class
        ];
    }
}

dump of the color created during loading process

 App\Entity\Color^ {#558
  -id: 221
  -name: "name"
  -code: "code"
  -fabrics: Doctrine\ORM\PersistentCollection^ {#542
    -snapshot: []
    -owner: App\Entity\Color^ {#558}
    -association: array:16 [ …16]
    -em: Doctrine\ORM\EntityManager^ {#171 …11}
    -backRefFieldName: "color"
    -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#451 …}
    -isDirty: false
    #collection: Doctrine\Common\Collections\ArrayCollection^ {#545
      -elements: []
    }
    #initialized: true
  }
}

People are also looking for solutions to the problem: php - Compare input of 2 inputs if it's the same

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.