phpsymfonydoctrinedoctrine-odmdoctrine-mongodb

Doctrine-MongoDB postLoad triggers preUpdate when creating new document


I have a model with some crypted fields, on postLoad I uncrypt the fields (works well) and I try to create a new document (a log to keep track of the reading).

My problem is, if I flush my new Log document into this postLoad, a preUpdate for my model is triggered, and I don't understand why. The model hasn't changed (the hydrated crypted fields are NotSaved), and even if it has changed, into a postLoad it should not trigger another update ?

Thanks for your ideas.

(php 7.1 with alcaeus/mongo-php-adapter).

EDIT : Adding some precisions :

The postLoadListener :

public function postLoad(LifecycleEventArgs $eventArgs) {
    $document = $eventArgs->getDocument();

    if ($document instanceof CryptedDocumentInterface) {
        $dm = $eventArgs->getDocumentManager();
        $this->cryptService->uncryptDocument($document);
        $this->logManager->record($document->getUser(), $document->getCryptedType(), null, null, $document->getId());
        $dm->flush();
    }
}

The uncryptDocument method uncrypt a serialized json of the crypted parameters and hydrate the document with it. Those parameters are @ODM\NotSaved. So the document should not be updated.

The logManager->record create a new Log document (whish doesn't implement CryptedDocumentInterface) and persist it. As you can see it is flushed into the postLoad.

In the logs I see that the Log document is correctly inserted and after that, a preUpdate is triggered for the crypted document I read. Here is the preUpdate :

public function preUpdate(LifecycleEventArgs $eventArgs) {
    $document = $eventArgs->getDocument();

    if ($document instanceof CryptedDocumentInterface) {
        $this->monolog->debug(__METHOD__ . ' ' . get_class($document) . ' id : ' . $document->getId()); // The id of the document I read.
        $values = $this->cryptService->cryptDocument($document);

        $dm     = $eventArgs->getDocumentManager();
        $class  = $dm->getClassMetadata(get_class($document));
        $dm->getUnitOfWork()->recomputeSingleDocumentChangeSet($class, $document);

        $this->logManager->record($document->getUser(), $document->getCryptedType(), $values['oldValue'], $values['newValue'], $document->getId());
    }
}

Solution

  • So, I resolved this by persisting/flushing my Log into another instance of DocumentManager. The LogManager::record create a DM, persist and flush my Log. The application DM is not impacted by doing this.