5

これにタイトルを付ける方法や、すでに投稿されている質問を検索する方法が本当にわからなかったので、これが以前にここで見られたことがある場合は、お詫び申し上げます。

次のコードで望ましくない結果が得られます。

// get object managers
$fooManager = $this->getContainer()->get('foo_manager');
$barManager = $this->getContainer()->get('bar_manager');

// infinite loop
for (;;) {

    // keep getting unitialized "foo" objects, or quit if none
    while (($foo = $fooManager->findUninitialized()) !== null) {

        // an uninitialized "foo" will need to make a "bar" object
        $bar = $barManager->create();
        $bar->setA('...');

        // save "bar" to database, update() WILL perform a flush()
        $barManager->update($bar);

        // make the association of "bar" to "foo"
        $foo->setBar($bar);

        // save "foo" to database, update() WILL perform a flush()
        $fooManager->update($foo);

    }

    // keep getting unprocessed "foo" objects, or quit if none
    while (($foo = $fooManager->findUnprocessed()) !== null) {

        // process the data from "foo" object's "bar"
        process($foo->getBar()->getB());

    }

}

while最初のループで、$barオブジェクトが作成され、データベースに配置されていることがわかります。別のスクリプトは、これらを拾い上げて、それらに何かをすることです。

2番目のwhileループでは、$fooオブジェクトは変更された「バー」オブジェクトにアクセスしようとしています(getB()呼び出されていることに注意してください。別のスクリプトでsetB()は、オブジェクトの状態を変更するために個別に実行されていると想定できます)。

ただし、2番目のループでは、を呼び出すと、他のスクリプトでgetB()設定した値が返されません。setB()

すべてのデータがデータベースに適切に永続化(およびフラッシュ)されていることを確認できるため、getB()その2番目のループでが呼び出されると、「B」を保持していたものが変更され、データベースに存在します。

私が気づいたことの1つは、ログファイルで$foo->getBar()、2番目のループを呼び出したときに「bar」のデータをプルするクエリが表示されないことです(これらは遅延ロードされるはずです)。また、 2番目のループでvar_dump()返された値を$foo->getBar()使用すると、関連付けられた「bar」オブジェクトが最初のループの終わりまでに表示されるのとまったく同じように見えます。

ある種のキャッシュまたは何かが起こっていると思います(スクリプトの実行の早い段階でこれらの「バー」オブジェクトを変更したため、Doctrineはデータベースからデータを再ロードするのではなく、単にそれらを再利用しているようです)。

私がやろうとしていることはおそらく一般的ではないことを私は知っています。私がやっていることは、Symfony2コンソールコマンド機能を使用して、いくつかのデータの処理に役立ついくつかのコマンドライン「デーモン」を作成することです。このコードを含む「デーモン」は、作成される「バー」オブジェクトを処理する別の「デーモン」と組み合わせて実行されます。

メソッドを呼び出したときに2番目のループのどこにこれを修正する方法があるかどうかについて知り$foo->getBar()たいのですが、実際にはデータベースから更新されたデータを取得しています。どんな助けでも大歓迎です。

4

1 に答える 1

28

これは実際にはユーザーChocoDeveloperによって提供されました。refresh($entity)エンティティマネージャのメソッドを利用することで、私の問題は解決しました。

例えば:

$em->refresh($entity);
于 2013-03-24T12:56:33.800 に答える