Атомарные операции с Doctrine MongoDB ODM

Я не могу заставить следующий запрос работать. По сути, я пытаюсь добавить документ сообщения в документ беседы, как показано ниже :

public function reply($conversationId, Message $message, $flush = true)
{            
    $this->dm->createQueryBuilder($this->class)
        ->field('archivers')->unsetField()
        ->field('repliedBy')->set($message->getUserId())
        ->field('repliedBody')->set($message->getBody())
        ->field('repliedAt')->set(new \DateTime())
        ->field('modifiedAt')->set(new \DateTime())
        ->field('messages')->push($message)
        ->field('id')->equals(new \MongoId($conversationId))
        ->getQuery()
        ->execute();

    if ($flush) {
        $this->dm->flush();
    }
}

. Этот метод ответа вызывается двумя способами. Во-первых, пользователь отправляет сообщение через html-форму, а во-вторых, с помощью вызова REST, сделанного приложением Android. Форма работает, но вызов REST терпит неудачу (, остальная реализация использует JMSSerializerBundle с FOSRestBundle между прочим )...

Я проверил, что код вызывается, и параметры, переданные методу, действительны в обоих случаях, но по какой-то причине вызов фиксации ()внутри UnitOfWork.php игнорирует изменения в документе. См. строку 413 , чтобы понять, что я имею в виду.

Кто-нибудь знает, почему это может происходить?

Ниже приведены другие подходы, которые я пробовал :

. Во-первых, я добавил вызов обновления (), который завершается с ошибкой "Catchable Fatal Error :Object of class... не может быть преобразован в строку в строке /vendor/bundles/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php. 280".

public function reply($conversationId, Message $message, $flush = true)
{            
    $this->dm->createQueryBuilder($this->class)
        ->update()
        ->field('archivers')->unsetField()
        ->field('repliedBy')->set($message->getUserId())
        ->field('repliedBody')->set($message->getBody())
        ->field('repliedAt')->set(new \DateTime())
        ->field('modifiedAt')->set(new \DateTime())
        ->field('messages')->push($message)
        ->field('id')->equals(new \MongoId($conversationId))
        ->getQuery()
        ->execute();

    if ($flush) {
        $this->dm->flush();
    }
}

Второй подход, который я пробовал, заключался в отправке массива вместо объекта :

public function reply($conversationId, Message $message)
{            
    $this->dm->createQueryBuilder($this->class)
        ->update()
        ->field('archivers')->unsetField()
        ->field('repliedBy')->set($message->getUserId())
        ->field('repliedBody')->set($message->getBody())
        ->field('repliedAt')->set(new \DateTime())
        ->field('modifiedAt')->set(new \DateTime())
        ->field('messages')->push(array(
            '_id' => new \MongoId(),
            'userId' => $message->getuserId(),
            'body' => $message->getBody(),
            'createdAt' => new \DateTime(),
            'modifiedAt' => new \DateTime(),
        ))
        ->field('id')->equals(new \MongoId($conversationId))
        ->getQuery() 
        ->execute();

    $this->dm->flush();
}

. Что отлично работает до тех пор, пока не будет вызван метод flush (). Сброс ()приводит к перемещению повторяющихся объектов. Итак, я получаю две копии одного и того же сообщения в беседе (, комментируя, что сброс ()решает проблему, но приложение имеет несколько вызовов сброса ()в других классах ).

Еще один push-запрос, который не работает с объектом:

public function archive($conversationId, $userId)
{

    $userStamp = new UserStamp();
    $userStamp->setUserId($userId);

    $this->dm->createQueryBuilder($this->class)
        ->update()
        ->field('archivers')->push($userStamp)
        ->field('modifiedAt')->set(new \DateTime())
        ->field('id')->equals(new \MongoId($conversationId))
        ->getQuery()
        ->execute();
}

Если убрать вызов push (), все работает нормально.

Еще застрял на этом моменте.

5
задан Burak 4 August 2012 в 04:22
поделиться