theofidry / AliceDataFixtures

Nelmio Alice extension to persist the loaded fixtures.
MIT License
311 stars 71 forks source link

Issue with fixtures persistence order due to doctrine/orm change #224

Closed adrienfr closed 11 months ago

adrienfr commented 1 year ago

Hi,

Since doctrine/orm 2.16, entities are not anymore processed in the same order than it was before :

Do not make any assumptions in your code about the number of queries it takes to flush changes, about the ordering of INSERT, UPDATE and DELETE queries or the order in which entities will be processed.

So if I have a fixture file like below:

App\Entity\Currency:
    currency1:
        from_currency: EUR
        to_currency: USD
        rate: 1.1320
    currency2:
        from_currency: EUR
        to_currency: GBP
        rate: 0.8855
    currency3:
        from_currency: USD
        to_currency: EUR
        rate: 0.8832

I can't anymore rely on the fact that $this->em->getRepository(Currency::class)->findAll()[0]will be currency1.

Would it be possible to ensure that our entity fixtures are inserted in the exact same order that they are sorted in our fixture files? Sometimes entities don't have any timestamp to rely on and the incremental ID is the only way to order them properly.

I'm not sure how this could be done, as with entities with relations (OneToMany, ManyToOne, ...) it could be an issue to flush earlier?

Thanks

mpdude commented 1 year ago

Are there any associations between these entities? If not, the ORM should still insert them in the order they were given to EntityManager::persist()

alexislefebvre commented 1 year ago

I can't anymore rely on the fact that $this->em->getRepository(Currency::class)->findAll()[0]will be currency1.

You could call something like $this->em->getRepository(Currency::class)->findOneBy(['from_currency' => 'EUR', 'to_currency' => 'USD']) though, it will return the first currency, even if it's the last inserted.

adrienfr commented 1 year ago

Are there any associations between these entities? If not, the ORM should still insert them in the order they were given to EntityManager::persist()

Thanks, you're right my example here was a bit too simple, the problem only arises with entities that have relationships.

benjamind01 commented 1 year ago

Are there any associations between these entities? If not, the ORM should still insert them in the order they were given to EntityManager::persist()

I do not understand why an association would change the order of persisting, are we not supposed to insert the fixtures in the order they are received in a loader?

theofidry commented 1 year ago

I do not understand why an association would change the order of persisting, are we not supposed to insert the fixtures in the order they are received in a loader?

No, because the fixtures dependency graph is independent to the order of declaration. If you load multiple files and in the last file a fixture depends on a fixture of the first file for example, it will be created first. You can find a bit more information here: https://github.com/nelmio/alice/blob/master/CONTRIBUTING.md#architecture.

As for the persistence, this is done here. As you can see the loader doesn't really care about the order. What you can do however is either:

benjamind01 commented 1 year ago

Thank you for taking the time to explain me