我真的不知道如何爲此標題或搜索已發佈的問題,所以如果在此之前已經看到此問題,請致歉。Doctrine2 ORM不會刷新腳本以外的對象
我得到一些意外的結果用下面的代碼:
// 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
對象正在作出並投入數據庫。另一個腳本正在採取這些措施,併爲他們做事。
在第二while
循環中,$foo
對象試圖訪問它們的改性「欄中的」對象(注意getB()
被調用,我們可以假設,在另一個腳本被單獨執行setB()
用於改變對象的狀態)。
但是,在第二個循環中,當我呼叫getB()
時,它不會返回在另一個腳本中使用setB()
設置的值。
我可以確保所有的數據都被正確地保存(並刷新)到數據庫中,所以當在第二個循環中調用getB()
時,無論持有「B」是否被更改並存在於數據庫中。
我注意到的一件事是在日誌文件中,當我在第二個循環中調用$foo->getBar()
(這些應該被延遲加載)時,我沒有看到爲「bar」拉入數據的查詢。另外,如果我在第二個循環中從$foo->getBar()
返回的值爲var_dump()
,則看起來與第一個循環結束時看到的關聯「bar」對象完全相同。
我在想,有某種緩存或某些事情正在進行(因爲我在腳本執行的早期更改了這些「欄」對象,Doctrine似乎只是重新使用這些而不是重新加載它們來自數據庫的數據)。
我知道我在做什麼可能不常見。我正在使用Symfony2控制檯命令功能編寫一些命令行「守護進程」來幫助處理一些數據;包含此代碼的「守護程序」與另一個處理那些創建的「bar」對象的「守護程序」一起運行。
好奇的是,當我調用$foo->getBar()
方法時,是否有辦法解決這個問題,我實際上是從數據庫中提取更新的數據。任何幫助是極大的讚賞。
你試過嗎? '$ em-> refresh($ entity);' – ChocoDeveloper
謝謝!這確實奏效。我花了幾個小時搜索,我在文檔中找到的所有可能都是使用'$ em-> detach($ entity);'和'$ em-> merge($ entity);'的組合這對我來說並沒有什麼意義......我沒有在文檔中看到有關'refresh($ entity)'函數的任何信息。 – jzimmerman2011