0

我有一个带有一些加密字段的模型,在 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->record 创建一个新的 Log 文档(虽然没有实现 CryptedDocumentInterface)并将其持久化。如您所见,它已刷新到 postLoad。

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

1 回答 1

0

所以,我通过将我的日志持久化/刷新到另一个 DocumentManager 实例来解决这个问题。LogManager::record 创建一个 DM,持久化并刷新我的日志。执行此操作不会影响应用程序 DM。

于 2019-03-21T11:03:13.840 回答