Skip to content

The metadata persister flushes the application's unflushed changes #16

Open

Description

@loevgaard

Summary

DoctrineOrmBasedMetadataPersister::persist() calls flush() on the entity manager of the metadata entity, which is usually the application's default entity manager. It does this at kernel.finish_request whenever the client's metadata changed. flush() writes the whole unit of work, so changes the application made to managed entities but didn't flush are written to the database too.

This matters when an application changes entities without meaning to save them, for example:

  • recalculating something on a managed entity only to render it
  • a controller that changes entities and then throws: kernel.finish_request is also dispatched for the error response, so the half-done changes are written

Reproduction

In the test application from #13: client A has stored metadata. A request from client B changes A's entity without flushing, and sets B's own metadata:

$other = $entityManager->find(Metadata::class, $clientIdOfA);
$other->setMetadata(['changed' => 'in memory only']);

$client->metadata->set('foo', 'bar');

After the request, A's row contains {"changed":"in memory only"}. The same goes for any other entity managed by that entity manager.

Possible fixes

  • Write the row with DBAL instead of the unit of work: UPDATE, and INSERT if no row was updated, with the table and column names from the entity's class metadata. A failing INSERT then also doesn't close the entity manager (see Handle race conditions #5).
  • Let the application put the metadata entity in its own entity manager. The persister already asks the registry for the manager of the metadata class, but the bundle always registers its mapping with the default entity manager.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions