2

イベントの実行中doctrine-mongodb-odm-1.0.0-BETA10に基づいて、いくつかのカスタム ロジックを使用して提供しようとしています。\InitialDocumentpreUpdate

\InitialDocumentnew の初期状態として動作する必要がある状態を取得したとしましょう\StateDocument。私はこのようなことをしています:

class InitDocListener implements \Doctrine\Common\EventSubscriber {
    public function getSubscribedEvents()
    {
        return [
            Events::preUpdate
        ];
    }

    public function preUpdate($args){
        $document = $args->getDocument();
        if($document instanceOf InitialDocument && $document->getState() == 'mine'){
            $stateDocument = new \StateDocument();
            $stateDocument->setInitDocument($document);
            $args->getDocumentManager()->persist($stateDocument);
            //no flush cause recursion happens
        }
    }

}

prePersistイベントが\StateDocument発生しますが、新しいドキュメントはデータベースに保持されません。それに応じてpostPersistイベントが発生することはありません。

さらにいくつかのカスタム ロジックがありますが、すべてイベント スコープにあります。ある時点で、そのロジックは、ビジネス スコープでの作成プロセスに依存するInitialDocumentため、状態の更新イベントを停止する必要がある例外をスローする場合があります。InitialDocument\StateDocument

どうすればこの問題を解決できますか? changeSet 再計算の前に実行するイベントは、インスタンスpreFlushを決定しません。したがって、更新を「検索」して、それが適切な方法ではないと私に思わせるInitialDocumentのは、ある種のトリックです。preFlush適当にアドバイスお願いします。ありがとう。

4

1 に答える 1

5

私はあなたのユースケースのテストケースをここに作成しました。質問のコードで際立っていたのはrecomputeSingleDocumentChangeSet()、ドキュメントに記載されているように、ライフサイクル コールバック中に変更していたドキュメントを呼び出してpreUpdateなかったことです。しかし、その呼び出しでも、新しいドキュメントは挿入されません。これは、UnitOfWork が挿入とアップサートの後に更新を実行するためです。完全な順序は、 UnitOfWork のcommit()メソッドで確認できます。

  • ドキュメントのアップサート
  • 書類の挿入物
  • ドキュメントの更新
  • 追加の更新 (永続化クラスによって内部的にスケジュールされます)
  • コレクションの削除
  • コレクションの更新
  • ドキュメントの削除

イベントがディスパッチされると、preUpdate新しいドキュメントの upserts/inserts が既に発生しています。を呼び出しても、ドキュメントの挿入をスケジュールすることになりますが、UnitOfWork はこれを無視し、ここでrecomputeSingleDocumentChangeSet()すべてのスケジュール キューをクリアするときに最終的に設定を解除します。

簡単な解決策は、ODM が更新の処理後に追加の挿入をチェックすることですが、状況によっては無限ループにつながる可能性があります。UnitOfWork の順序付けは、プロジェクトでの私の作業よりも前のものですが、元の実装が考えられたとき、ループのリスクが懸念された可能性があります。

回避策として、他のコンテナー (またはリスナー自体) に挿入される新しいドキュメントをリスナーにダンプさせ、追加のドキュメントが永続化/フラッシュされるかどうかを後で確認することができます。

于 2014-05-29T15:29:26.670 に答える