Bonjour à tous,
Malgré la documentation et la vidéo de grafikart sur les fixtures symfony, je ne parviens pas à solutionner mon problème.
J'utilise symfony 7 / doctrine-fixtures-bundle 4.1
J'ai 2 fixtures. UserFixtures et ProfilFixtures.
l'objet User a besoin d'un objet Profil préalablement créé.
Ma fixture ProfilFixtures :
namespace App\DataFixtures;
use App\Entity\Profil;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class ProfilFixtures extends Fixture
{
public const PROFIL_STANDARD = 'profil_standard';
public function load(ObjectManager $manager): void
{
$profil = new Profil();
$profil->setName('STANDARD');
$profil->setCreatedAt(new \DateTime('now'));
$profil->setCreatedBy('André DUPONT');
$manager->persist($profil);
$manager->flush();
$this->addReference(self::PROFIL_STANDARD, $profil);
}
}
Ma fixture UserFixtures :
namespace App\DataFixtures;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserFixtures extends Fixture
{
private $userPasswordHasher;
public function __construct(UserPasswordHasherInterface $userPasswordHasher)
{
$this->userPasswordHasher = $userPasswordHasher;
}
public function load(ObjectManager $manager): void
{
$user = new User();
$user->setEmail('dupont@aa.com');
$user->setRoles(['ROLE_USER']);
$user->setProfil($this->getReference(ProfilFixtures::PROFIL_STANDARD, Profil::class));
$user->setPassword($this->userPasswordHasher->hashPassword($user, 'password'));
$manager->persist($user);
$manager->flush();
}
}
Lorsque je charge mes fixtures, j'ai l'erreur :
Reference to "profil_standard" for class "App\DataFixtures\Profil" does not exist
Pourtant la fixture ProfilFixtures est bien chargée avant celle des utilistateurs dans la console:
purging database
loading App\DataFixtures\ProfilFixtures
loading App\DataFixtures\UserFixtures
Si je log ma référence directement dans ProfilFixtures :
dd($this->getReference(ProfilFixtures::PROFIL_STANDARD, Profil::class));
elle s'affiche bien dans la console :
^ App\Entity\Profil^ {#670
-id: 38
-name: "STANDARD"
-created_at: DateTime @1746522834 {#674
date: 2025-05-06 09:13:54.818294 UTC (+00:00)
}
-created_by: "André Dupont"
-updated_at: null
-updated_by: null
}
J'ai suivi la doc sur le partage d'objet ici :
https://symfony.com/bundles/DoctrineFixturesBundle/current/index.html#sharing-objects-between-fixtures
Mais cela ne fonctionne pas.
Si quelqu'un peut m'éclairer
Je vous remercie d'avance
Ton problème vient du fait que pour utiliser getReference() dans une fixture, ta fixture doit implémenter l’interface DependentFixtureInterface pour garantir que l’ordre de chargement et la gestion des références soit respecté.
Actuellement, ta UserFixtures ne le fait pas : du coup Symfony n’est pas sûr que ProfilFixtures a été chargée avant, et la référence n’est pas dispo dans le contexte d’exécution de la fixture.
Voici ce que tu dois faire pour que ça marche, sans blabla :
⸻
1. Modifie ta UserFixtures pour qu’elle étende DependentFixtureInterface :
<?php
namespace App\DataFixtures;
use App\Entity\User;
use App\Entity\Profil;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
class UserFixtures extends Fixture implements DependentFixtureInterface
{
private $userPasswordHasher;
public function __construct(UserPasswordHasherInterface $userPasswordHasher)
{
$this->userPasswordHasher = $userPasswordHasher;
}
public function load(ObjectManager $manager): void
{
$user = new User();
$user->setEmail('dupont@aa.com');
$user->setRoles(['ROLE_USER']);
$user->setProfil($this->getReference(ProfilFixtures::PROFIL_STANDARD)); // PAS besoin de préciser Profil::class ici
$user->setPassword($this->userPasswordHasher->hashPassword($user, 'password'));
$manager->persist($user);
$manager->flush();
}
public function getDependencies()
{
return [
ProfilFixtures::class,
];
}
}
Points importants :
• N’utilise PAS le 2ème argument (Profil::class) dans getReference() – la méthode attend seulement la clé, c’est tout.
• Implémente bien getDependencies() pour garantir l’ordre d’exécution.
⸻
2. Laisse ProfilFixtures tel quel :
Ta fixture est OK, tu n’as rien à toucher dessus.
⸻
3. Recharge tes fixtures :
php bin/console doctrine:fixtures:load
Ça fonctionnera direct, la référence sera trouvée et injectée dans ton User.
Si tu as encore un problème, vérifie que tu utilises la bonne clé (profil_standard) dans addReference() et dans getReference().
Attention aussi à l’orthographe : “profil_standard” maybe.
⸻
En résumé :
• Ta fixture qui dépend d’une autre doit implémenter DependentFixtureInterface
• Ajoute la méthode getDependencies()
• Utilise juste la clé dans getReference()
Direct, propre, efficace.
J'ai le même problème depuis plusieurs jours sur un projet Symfony 7 également. Impossible de trouver une solution ailleurs sur l'internet.
As-tu trouvé une solution entre temps ?
Autrement, il faudrait reposer la question sur un forum plus fréquenté que celui-ci (StackOverflow ou Reddit).
Salut CHA-NOX.
Yes, j'ai trouvé la solution. il fallait juste que ma fixtures users implémente de DependentFixtureInterface (pas oublié le use)
<?php
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
class UserFixtures extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
$user1 = new User();
$user1->setEmail('jean.dupont@gmail.com');
$user1->setRoles(['ROLE_USER']);
$user1->setProfil($this->getReference(ProfilFixtures::PROFIL_STANDARD, Profil::class));
$manager->persist($user1);
$manager->flush();
}
}
et ensuite la référence à mes profils existaient.
Péviens mois si ton soucis persiste
Bonjour Bulgore !
J'ai trouvé la solution à mon cas en parallèle. Pour ma part, j'avais correctement implémenté le DependentFixtureInterface, mais j'avais utilisé la classe de la fixture au lieu de la classe de l'entité pour le getReference(). (J'ai mis tout ce temps à remarquer un détail aussi simple... 🥲)
C'est cool que tu aies pu trouver une solution à ton problème, et merci aussi à Slabb pour sa réponse ! =D
C'est top de l'entendre CHA-NOX !
Encore mieux que tu ai solutionné par toi même c'est comme ça qu'on devient forgeron :)