28

I am using Symfony 3.4.0, I try to load fixtures with:

php bin/console doctrine:fixtures:load

An error occurred while creating the data, what's wrong?

enter image description here

zatamine
  • 3,458
  • 3
  • 25
  • 33
Alexander
  • 311
  • 1
  • 3
  • 6

11 Answers11

50

This command looks for all services tagged with doctrine.fixture.orm.
There is two ways to fix this problem.

First one: any class that implements ORMFixtureInterface will automatically be registered with this tag.

<?php

namespace AppBundle\DataFixtures\ORM;


use Doctrine\Bundle\FixturesBundle\ORMFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;

class LoadFixtures implements ORMFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        #your code
    }
}

Second one: You need manually tag doctrine.fixture.orm to DataFixtures in sevice.yml configuration.

services:
    ...

    # makes classes in src/AppBundle/DataFixtures available to be used as services
    # and have a tag that allows actions to type-hint services
    AppBundle\DataFixtures\:
        resource: '../../src/AppBundle/DataFixtures'
        tags: ['doctrine.fixture.orm']
GuRu
  • 1,880
  • 3
  • 23
  • 32
  • 1
    I have spend a lot of time trying to register my fixture data class. So, implementation of this interface "ORMFixtureInterface" - made my day :) Thank you Sir ! – kxko Mar 29 '18 at 11:09
  • Symfony says the same! quote: "If you're using the default service configuration, any class that implements ORMFixtureInterface will automatically be registered with this tag." https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#loading-fixtures – Muzafar Ali May 05 '18 at 12:00
10

I tried @Alexander's solution but it's doesn't work for me.

I had resolved the same problem by adding the tag service to the class, Symfony doc on the services.yml file bundle:

BlogBundle/Resources/config/services.yml

Services:
...
# Fixtures services
    BlogBundle\DataFixtures\ORM\PostFixture:
        tags: [doctrine.fixture.orm]
...

My BlogBundle/DataFixtures/ORM/PostFixture.php class :

...
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
...

class PostFixture implements FixtureInterface
{
public function load(ObjectManager $manager)
    {
...
}
}

Source Inspiration : Synfony doc -> Service container -> The autoconfigure Option

Hope it'll an alternative solution

zatamine
  • 3,458
  • 3
  • 25
  • 33
  • 1
    This solution is working fine. I started getting this error when I upgraded doctrine-fixtures from v2.4.1 to 3.0.2. – Praveesh Dec 06 '17 at 06:44
4

In 4.0.1 I have to implement service configuration to show Symfony my DataFixtures folder:

in config/services.yaml

services:

    ...

    App\DataFixtures\:
        resource: '%kernel.project_dir%/src/DataFixtures'
        tags: [doctrine.fixture.orm]

if my class IMPLEMENTS FixtureInterface and without this config if it is EXTENDS Fixture

Wishmaster
  • 1,102
  • 14
  • 20
4

Example for reusable bundle.

src/Acme/Bundle/UserBundle/DataFixtures/ORM/DataFixtures.php

<?php 
namespace Acme\Bundle\UserBundle\DataFixtures\ORM;

use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;

class DataFixtures extends Fixture
{
    /**
     * Load data fixtures with the passed EntityManager
     *
     * @param ObjectManager $manager
     */
    public function load(ObjectManager $manager)
    {
       #your code
    }
}

in app/config/services.yml

Acme\Bundle\UserBundle\DataFixtures\:
     resource: '../../src/Acme/Bundle/UserBundle/DataFixtures/'

append your fixtures data:

php bin/console doctrine:fixtures:load --append
mshv
  • 41
  • 1
2

~/dev/domain.lan/src/ProductBundle/DataFixtures/ORM/ProductF‌​ixture.php

<?php

namespace ProductBundle\DataFixtures\ORM;

use Doctrine\Bundle\FixturesBundle\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use ProductBundle\Entity\Product;

class ProductFixture implements FixtureInterface
{

    public function load(ObjectManager $manager)
    {
       // create 20 products! Bam!
       for ($i = 0; $i < 20; $i++) {
           $product = new Product();
           $product->setName('Product name' . $i);
           $manager->persist($product);
       }

       $manager->flush();
    }
}

The problem is solved it was necessary to add a service: (app/config/services.yml)

services:
    # Product service
    ProductBundle\:
        resource: '../../src/ProductBundle/*'
        exclude: '../../src/ProductBundle/{Entity,Repository,Tests}'
Alexander
  • 311
  • 1
  • 3
  • 6
  • My be you should add it on the `services.yml` bundle file ex: `~/dev/domain.lan/src/ProductBundle/Resoueces/config/services.yml` – zatamine Dec 03 '17 at 20:24
1

use Doctrine\Bundle\FixturesBundle\Fixture

class ProductFixture extends Fixture implements FixtureInterface

see documentation: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html

1

After long research, found a solution. This work with :

  • doctrine/doctrine-fixtures-bundle: ^3.0,
  • Symfony ^3.3

First

  • Define your Fixture.
<?php
namespace Where\MyFixtureBundle\FileFolder\IsLocated;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Nao\UserBundle\Entity\User;

class LoadData implements FixtureInterface
{
    /**
     * Load data fixtures with the passed EntityManager
     *
     * @param ObjectManager $manager
     */
    public function load(ObjectManager $manager){
        $object = new Entity();
        $object->setFoo(bar)
        ...

        $manager->persist($object);

        $manager->flush();
    }
}

Next, define a service in the bundle's service.yml file or directly in "app/config/service.yml" (not recommanded)

# Fixtures service
your_service.name:
    class: Full\Namespce\With\TheClassFixtureName
    tags: [doctrine.fixture.orm] <-- important

Don't forget, just to be sure the following

composer du -o or composer dump-autoload -o

Try to execute your command now for load your data fixtures.

Spartacvs1
  • 211
  • 3
  • 5
0

I also had to update the app/AppKernel.php and added the following the the bundles array:

new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle()
bananaCute
  • 433
  • 5
  • 17
0

After read above comment, i found solution inside @GuRu answer's :

"Second one: You need manually tag doctrine.fixture.orm to DataFixtures in sevice.yml configuration".

Then implements ORMFixtureInterface in your fixtures class.

. in fact, we have to add additionnal configuration inside services.yml to solve it. Important to know, i notice this issue in version ~3.4 of symfony.

Best regard

Diskary
  • 36
  • 5
  • What new this answer brings? Everything you said is already done in an answer and in a comment – Vega Sep 29 '18 at 14:04
0

I'm jumping here after several years just to document for myself the mixed of solution that I found in this thread.

I experienced the same issue and find the solution by using multiple answers and I hope it will help.

This were my code:

namespace App\DataFixtures;

use App\Entity\Book;
use App\Factory\{BookFactory, UserFactory};
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;

class AppFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        UserFactory::new()->createOne([
            'email' => 'user2@user.hr',
            'roles' => ['ROLE_ADMIN']
        ]);

        UserFactory::new()->createOne([
            'email' => 'user3@user.hr',
            'roles' => ['ROLE_USER']
        ]);

        BookFactory::new()->createMany(25);

        $manager->flush();
    }
}

so I changed replaced extends Fixture ORMFixtureInterface. So new code looks like this:

namespace App\DataFixtures;

use App\Entity\Book;
use App\Factory\{BookFactory, UserFactory};
use Doctrine\Bundle\FixturesBundle\ORMFixtureInterface;
use Doctrine\Persistence\ObjectManager;

class AppFixtures implements ORMFixtureInterface
{
    public function load(ObjectManager $manager): void
    {
        UserFactory::new()->createOne([
            'email' => 'user2@user.hr',
            'roles' => ['ROLE_ADMIN']
        ]);

        UserFactory::new()->createOne([
            'email' => 'user3@user.hr',
            'roles' => ['ROLE_USER']
        ]);

        BookFactory::new()->createMany(25);

        $manager->flush();
    }
}

then I went to services.yml and the I inserted this:

App\DataFixtures\:
        resource: '%kernel.project_dir%/src/DataFixtures'
        tags: ['doctrine.fixture.orm']

so services.yml file looks like this:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
    App\DataFixtures\:
        resource: '%kernel.project_dir%/src/DataFixtures'
        tags: ['doctrine.fixture.orm']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

and then, like @Spartacvs1 suggested, in your terminal execute this

composer dump-autoload -o
josips
  • 1
  • 1
0

I'd like to give some context to the problem, as the existing answers helped me but didn't solve my particular case.

Finding the classes depends upon the configuration of you service injection:

# app/config/services.yml

###
services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  DataFixtures\My\MyFixtures:
 
###
services:
  _defaults:
    autowire: true
    autoconfigure: false
    public: false

  my_fixtures:
    class: DataFixtures\My\MyFixtures
    tags:
      - doctrine.fixture.orm
    
###
services:
  _defaults:
    autowire: false
    autoconfigure: true
    public: false

  my_fixtures:
    class: DataFixtures\My\MyFixtures
    arguments:
      - '@fos_user.util.password_updater'

###
services:
  _defaults:
    autowire: false
    autoconfigure: false
    public: false

  my_fixtures:
    class: DataFixtures\My\MyFixtures
    tags:
      - doctrine.fixture.orm
    arguments:
      - '@fos_user.util.password_updater'

For the given class:

# fixtures/My/MyFixtures.php
<?php
declare(strict_types=1);

namespace DataFixtures\My;

use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;

use FOS\UserBundle\Model\User;

class MyFixtures extends Fixture
{
    public function __construct(PasswordUpdaterInterface $passwordUpdater)
    {
        $this->passwordUpdater = $passwordUpdater;
    }

    public function load(ObjectManager $om): void
    {
        $user = new User;
        $user->setUsername('toto');
        $user->setPlainPassword('tata');
        $this->passwordUpdater->hashPassword($user);
        $user->setEmail('toto@lupusmic.org');
        $user->setEnabled(true);

        $om->persist($user);
        $om->flush();
    }

    private $passwordUpdater;
    private $om;
}

The composer.json:

# composer.json
{
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests",
            "DataFixtures\\": "fixtures"
        }
    },
}

Loading in the AppKernel:

# app/AppKernel.php
public function registerBundles()
{
    $bundles = [];
    // ...

    // isTestEnvironement is a custom method to determine if `--env=test` given on CLI
    if ($this->isTestEnvironement()) {

        $bundles[] = new
            Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
    }
    
    // ...
    return $bundles;
}