简体   繁体   English

创建新文档时,Doctrine-MongoDB postLoad会触发preUpdate

[英]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). 我有一个带有一些加密字段的模型,在postLoad上,我将这些字段解密(工作正常),然后尝试创建一个新文档(记录日志以跟踪读数)。

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. 我的问题是,如果将新的Log文档刷新到此postLoad中,则会触发模型的preUpdate,而我不明白为什么。 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 ? 模型未更改(水合加密字段未保存),即使已更改,也已更改为postLoad,它是否不应触发其他更新?

Thanks for your ideas. 谢谢你的想法。

(php 7.1 with alcaeus/mongo-php-adapter). (带有alcaeus / mongo-php-adapter的php 7.1)。

EDIT : Adding some precisions : 编辑:添加一些精度:

The postLoadListener : 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. uncryptDocument方法解密了加密参数的序列化json并用它水合文档。 Those parameters are @ODM\\NotSaved. 这些参数是@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. logManager-> record创建一个新的Log文档(whish没有实现CryptedDocumentInterface)并保留它。 As you can see it is flushed into the postLoad. 如您所见,它被刷新到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. 在日志中,我看到正确插入了日志文档,之后,为我读取的加密文档触发了preUpdate。 Here is the preUpdate : 这是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());
    }
}

So, I resolved this by persisting/flushing my Log into another instance of DocumentManager. 所以,我通过将我的Log持久/刷新到另一个DocumentManager实例来解决这个问题。 The LogManager::record create a DM, persist and flush my Log. LogManager :: record创建DM,持久化并刷新我的日志。 The application DM is not impacted by doing this. 这样做不会影响应用程序DM。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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