Doctrine-MongoDB 创建新文档时 postLoad 触发 preUpdate
Doctrine-MongoDB postLoad triggers preUpdate when creating new document
我有一个带有一些加密字段的模型,在 postLoad 上我解密了这些字段(效果很好),然后我尝试创建一个新文档(一个日志来跟踪阅读)。
我的问题是,如果我将新的日志文档刷新到此 postLoad 中,则会触发模型的预更新,但我不明白为什么。模型没有改变(水合加密字段未保存),即使它已经改变,进入 postLoad 它不应该触发另一个更新?
谢谢你的想法。
(php 7.1 与 alcaeus/mongo-php-adapter).
编辑:添加一些精度:
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 文档(whish 没有实现 CryptedDocumentInterface)并保存它。如您所见,它被刷新到 postLoad 中。
在日志中,我看到日志文档已正确插入,之后,为我读取的加密文档触发了 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());
}
}
因此,我通过 persisting/flushing 我登录另一个 DocumentManager 实例解决了这个问题。 LogManager::record 创建一个 DM,保留并刷新我的日志。这样做不会影响应用程序 DM。
我有一个带有一些加密字段的模型,在 postLoad 上我解密了这些字段(效果很好),然后我尝试创建一个新文档(一个日志来跟踪阅读)。
我的问题是,如果我将新的日志文档刷新到此 postLoad 中,则会触发模型的预更新,但我不明白为什么。模型没有改变(水合加密字段未保存),即使它已经改变,进入 postLoad 它不应该触发另一个更新?
谢谢你的想法。
(php 7.1 与 alcaeus/mongo-php-adapter).
编辑:添加一些精度:
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 文档(whish 没有实现 CryptedDocumentInterface)并保存它。如您所见,它被刷新到 postLoad 中。
在日志中,我看到日志文档已正确插入,之后,为我读取的加密文档触发了 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());
}
}
因此,我通过 persisting/flushing 我登录另一个 DocumentManager 实例解决了这个问题。 LogManager::record 创建一个 DM,保留并刷新我的日志。这样做不会影响应用程序 DM。