简体   繁体   中英

Altering another document in Doctrine ODM PreUpdate event

Fairly new at MongoDB and Doctrine both. I'm currently setting up a model system for my framework, and trying to implement the events.

The idea is this: When a certain model gets updated, a new user (also a model) should be created/updated. I do this all in the PreUpdate event so I can catch the changes made (check if the e-mail address on the model has been changed).

Creating and persisting a new model in this event works like a charm, however when I try to update a user I'm unable to save the data. I tried flushing but this causes an infinite loop (which I can understand why, as he tries to flush the same document again).

Any ideas on what way I should get this done? Tried recomputeSingleDocumentChangeSet on the unit of work for the user, but this doesn't seem to save anything.

Tried recomputeSingleDocumentChangeSet on the unit of work for the user, but this doesn't seem to save anything.

This is exactly what you should do (after modifying the user field)

$user->setSomething(true);
$uow->recomputeSingleDocumentChangeSet(/* ... */);

and nothing else, especially don't use flush as you are inside flush already. The recomputeSingleDocumentChangeSet makes Doctrine recount changes which will be later included in the update query of document.

Creating and persisting a new model in this event works like a charm

This however sounds strange as new objects persisted at the time of preUpdate event should not reach database (unless you have issued another flush which may have unwanted side effects at this point) as insertions are handled before updates.

You can resolve this issue by recalculating the UnitOfWork-Changeset after having changed the respective field value.

Without this ChangeSet recalculation, only fields that are already scheduled to update are taken into account. Any additional changes via $entity->setField() will be ignored whereas attempts to directly use $eventArgs->setNewValue($field, $value) will result in an error, as the latter only accepts modifications of values which are already part of the current UnitOfWork - change set.

You can trigger this operation via:

/** @var ObjectManager $em */
$om = $args->getObjectManager();
$om->getUnitOfWork()->recomputeSingleDocumentChangeSet($om->getClassMetadata($entity::class), $entity);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM