次のクエリが機能しないようです。基本的に、以下に示すように、会話ドキュメントにメッセージドキュメントを追加しようとしています。
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();
}
}
このreplyメソッドは2つの方法で呼び出されます。最初にユーザーがhtmlフォームを介してメッセージを投稿し、次にAndroidアプリケーションによって行われたREST呼び出しによって。フォームは機能しますが、REST呼び出しは失敗します(残りの実装はFOSRestBundleでJMSSerializerBundleを使用します)...
コードが呼び出され、メソッドに渡されたパラメーターがどちらの場合も有効であることを確認しましたが、何らかの理由で、UnitOfWork.php内のcommit()呼び出しはドキュメントへの変更を無視します。私が何を意味するかについては、413行目を参照してください。
なぜこれが起こっているのか誰かが知っていますか?
以下は私が試した他のアプローチです:
最初に、「Catchable Fatal Error:Object of class ... could not convert to string in /vendor/bundles/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php line 280」で失敗するupdate()呼び出しを追加しました。
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();
}
}
私が試した2番目のアプローチは、オブジェクトの代わりに配列をプッシュすることでした。
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()メソッドが呼び出されるまで正常に機能します。flush()により、重複するオブジェクトがプッシュされます。そのため、会話で同じメッセージの2つのコピーを取得します(flush()にコメントすると問題は解決しますが、アプリケーションには他のクラスに複数のflush()呼び出しがあります)。
オブジェクトで失敗する別のプッシュクエリ:
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()呼び出しを削除すると、すべて正常に機能します。
この時点ではまだ立ち往生しています。