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

时间:2019-03-15 20:43:01

标签: php symfony doctrine doctrine-odm doctrine-mongodb

我有一个带有一些加密字段的模型,在postLoad上我解密了这些字段(效果很好),然后尝试创建一个新文档(一个记录阅读情况的日志)。

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

感谢您的想法。

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

编辑:添加一些精度:

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();
    }
}

uncryptDocument方法对加密参数的序列化json进行解密,并将其与文件混合在一起。这些参数是@ODM \ NotSaved。因此,不应更新文档。

logManager->记录创建一个新的Log文档(这没有实现CryptedDocumentInterface),并将其持久化。如您所见,它已刷新到postLoad中。

在日志中,我看到正确插入了日志文档,然后,为读取的加密文档触发了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());
    }
}

1 个答案:

答案 0 :(得分:0)

因此,我通过将Log持久/刷新到DocumentManager的另一个实例中来解决了这个问题。 LogManager :: record创建一个DM,保留并刷新我的日志。这样做不会影响应用程序DM。