fzaninotto / Faker

Faker is a PHP library that generates fake data for you
MIT License
26.8k stars 3.57k forks source link

Doctrine Populator: Don't clean entity manager #2024

Closed obstschale closed 3 years ago

obstschale commented 3 years ago

Summary

I have 2 entitys. They have a ManyToOne relationship. When I seed the DB I get an error, that the entity manager thinks there are non-persisted entities.

Versions

Version
PHP 7.4.5
fzaninotto/faker 1.9.1

Self-enclosed code snippet for reproduction

$generator = \Faker\Factory::create('de_DE');
$populator = new Populator($generator, self::entityManger());
$populator->addEntity(AccountType::class, 2);
$populator->addEntity(AccountClass::class, 10);
$inserted = $populator->execute();

Expected output

2 AccountTypes are persisted and 10 AccountClasses with relationships of AccountType

Actual output

1) MtTestCase::testSeeder
Doctrine\ORM\ORMInvalidArgumentException: Multiple non-persisted new entities were found through the given association graph:

 * A new entity was found through the relationship 'App\AccountClass\AccountClass#accountType' that was not configured to cascade persist operations for entity: App\AccountType\AccountType@00000000615169460000000030020730. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\AccountType\AccountType#__toString()' to get a clue.

Explanation

In Doctrine\Populator::execute() Line 105 the entity manager is cleaned after each entity class. That means, the populator persists AccountType and that works. But now it cleans the entity manager before creating and persisting AccountClasses. The Populator uses the before inserted AccountTypes correctly, but the entity manage does not know them and thinks they are not persisted.

Our Doctrine Relationship is not set up to cascade:persist, hence Doctrine does not persist (again) the AccountType objects and the error is thrown.

If I comment line 105 everything works fine.

Does anyone know a workaround? Or may I start a PR to handle the cleaning differntly. For example with a flag to clean after everything is persisted.

obstschale commented 3 years ago

I just found this commit https://github.com/fzaninotto/Faker/commit/5337ce5261b393937bd7aaebb21020159756a152 related to https://github.com/fzaninotto/Faker/issues/1862. This should fix my issue, when a new version is available. Hence I close this issue.