簡體   English   中英

Doctrine2錯誤地緩存查詢結果

[英]Doctrine2 incorrectly caching a query result

使用Symfony3的標准管理器的查詢生成器,我創建以下查詢:

$anagrafica = $em->createQueryBuilder()
    ->select("a, rel, a2")
    ->from("AppBundle\Entity\Anagrafica\anagrafica", "a")
        ->leftJoin("a.relazioniDa", "rel")
        ->leftJoin("rel.anagrafica_figlio", "a2")
    ->where("a.stato = :actStatus")
        ->andWhere("a = :anagrafica")
        ->andWhere($em->createQueryBuilder()->expr()->orX("a.id = :id", "a2.id = :id"))
    ->setParameter("anagrafica", $anagraficaInserente)
        ->setParameter("actStatus", $actStatus)
        ->setParameter("id", $id)
    ->getQuery()->getResult();

這基本上選擇了父實體“ a”和子實體“ a2”。 他們兩個都屬於同一類。

當我使用2作為“ id”參數運行此查詢時,該查詢會正確合並結果,並向我返回a.id = 1和a.id = 2的單個結果。

之后,我立即將查詢設置3作為ID重新運行; 這次,結果應為一個,其中a.id = 1和a2.id = 3,但實際結果與id = 2時相同。
如果我僅在id = 3的情況下運行查詢,則結果將再次正確合並。

我最好的猜測是該學說正在緩存結果,由於某種原因,當我更改id時,它實際上並未重新執行查詢(盡管參數轉儲在id字段中顯示了正確的值);
在線搜索的結果很差; 我發現了有關此問題的舊的(和固定的)錯誤報告,並且對查詢禁用的任何類型的緩存都沒有帶來任何改善。

我可以通過僅獲取主要實體,然后手動查看子實體來解決該問題,但我真的很想知道,是否有一種方法可以在本地禁用緩存或其他某種數據庫端解決方案。

編輯:我在測試環境中有此問題; 這2個查詢在2個不同的(但連續的)函數調用中執行

您的問題不是某種查詢緩存,而是對實體管理器工作方式的誤解。

實體管理器跟蹤從數據庫加載的所有對象。 當你的第二個查詢的結果是水合,它看到這個特殊的a實體已經進行了水合,所以它給你一個已經由第一個查詢(返回完全相同的PHP對象實例$a_from_first_query === $a_from_second_query )。 來自第二個結果的rela2對象被添加到$a->relazioniDa集合中,該集合已經包含來自第一個查詢的rela2 在第二個查詢之后, $a->relazioniDa[0]->anagrafica_figlio->id將為2,而$a->relazioniDa[1]->anagrafica_figlio->id將為3。這也稱為增量水合。

為了防止這種情況,您可以通過調用$em->clear()兩個查詢之間的實體管理器。 不過,您必須記住,這意味着在clear()之前檢索到的所有實體的更改都不會在下一個flush()上保存到數據庫,因為實體管理器不再了解那些對象。 您還可以通過調用$em->detach($entity)從管理器中刪除單個對象,但是如果僅分離父對象,則可能會導致問題,您可能必須從第一個查詢中分離整個對象層次結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM