Doctrine-MongoDB запускает предварительную загрузку при создании нового документа

#php #symfony #doctrine #doctrine-odm #doctrine-mongodb

#php #symfony #доктрина #doctrine-odm #doctrine-mongodb

Вопрос:

У меня есть модель с некоторыми зашифрованными полями, при последующей загрузке я расшифровываю поля (работает хорошо) и пытаюсь создать новый документ (журнал для отслеживания чтения).

Моя проблема в том, что если я загружаю свой новый документ журнала в эту постзагрузку, запускается предварительное обновление для моей модели, и я не понимаю почему. Модель не изменилась (гидратированные зашифрованные поля не сохранены), и даже если она изменилась, при последующей загрузке она не должна запускать другое обновление?

Спасибо за ваши идеи.

(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-> запись создает новый документ журнала (который не реализует CryptedDocumentInterface) и сохраняет его. Как вы можете видеть, он сбрасывается при последующей загрузке.

В журналах я вижу, что документ журнала вставлен правильно, и после этого запускается предварительное обновление для зашифрованного документа, который я прочитал. Вот предварительное обновление :

 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. Возможно, ваш журнал добавлен в какую-то коллекцию в документе с зашифрованными полями? Вообще говоря, это слепое угадывание с предоставленной вами информацией.

2. Спасибо за ваш комментарий, я думал, что это скорее концептуальная ошибка, вроде сброса новых документов в событие жизненного цикла. Я добавил некоторые подробности в вопрос.

Ответ №1:

Итак, я решил это, сохранив / сбросив свой журнал в другой экземпляр DocumentManager. LogManager::record создает DM, сохраняет и очищает мой журнал. Это не влияет на DM приложения.