2014-05-07 15 views
2

我正在使用Symfony 2中的Doctrine 2的項目,我使用MEMCACHE來存儲原則的結果。 我從MEMCACHE中檢索到的對象有問題。學說2 - 如何在關係中使用從緩存中檢索的對象

我發現這個職位相似,但這種方法不解決我的問題:Doctrine detaching, caching, and merging

這是該方案

/** 
* This is in entity ContestRegistry 
* @var contest 
* 
* @ORM\ManyToOne(targetEntity="Contest", inversedBy="usersRegistered") 
* @ORM\JoinColumn(name="contest_id", referencedColumnName="id", onDelete="CASCADE")) 
* 
*/ 
protected $contest; 

和其他實體

/** 
* @var usersRegistered 
* 
* @ORM\OneToMany(targetEntity="ContestRegistry", mappedBy="contest") 
* 
*/ 
protected $usersRegistered; 

現在想象大賽是在緩存中,我想保存一個ContestRegistry條目。 所以我檢索對象的較量中緩存如下:

$contest = $cacheDriver->fetch($key); 
$contest = $this->getEntityManager()->merge($contest); 
return $contest; 

而作爲最後的操作我做的:

$contestRegistry = new ContestRegistry(); 
$contestRegistry->setContest($contest); 
$this->entityManager->persist($contestRegistry); 
$this->entityManager->flush(); 

我的問題是,這種理論正確保存新的實體,而且它使一個更新在實體大賽上,它會更新已更新的專欄。真正的問題是,它會爲每個條目進行更新查詢,我只是想添加對實體的引用。 我如何才能做到這一點? 任何幫助,將不勝感激。

回答

1

爲什麼

當實體合併回EntityManager的,它會被標記爲髒。這意味着執行刷新時,實體將在數據庫中更新。這似乎是合理的,我的,因爲當你做一個實體管理,你真正想要的EntityManager的管理它;)

在你的情況,你只需要在實體與另一個實體關聯,所以你不真的需要它是託管。我爲此提出了一種不同的方法。

使用參考

所以不合並$contest回EntityManager的,但抓住它的一個引用:

$contest = $cacheDriver->fetch($key); 
$contestRef = $em->getReference('Contest', $contest->getId()); 

$contestRegistry = new ContestRegistry(); 
$contestRegistry->setContest($contestRef); 

$em->persist($contestRegistry); 
$em->flush(); 

該引用將是一個代理服務器(除非它已經管理的),並且根本不會從數據庫加載(甚至在刷新EntityManager時也不會)。

結果緩存

在使用你的代替自己的緩存機制,你可以使用學說的result cache。它會緩存查詢結果以防止數據庫訪問,但是(如果我沒有弄錯的話)仍會保留這些結果。這可以防止您可以通過緩存實體本身獲得很多問題。

+0

嗨,我試了兩種解決方案,第一個不起作用。我不知道爲什麼。參考它的作品。也許當我更改跟蹤策略時,我應該修改關係中涉及的所有實體? – stuzzo

+0

我已經研究過這個問題,而且看起來實體被標記爲髒,不管更改跟蹤策略如何。所以這不是一個選項。我已經更新了我的答案。 –

+0

順便說一句:我建議使用_Deferred Explicit_作爲_all_你的實體,因爲刷新變得便宜很多。想象一下,你裝載了5000個實體並改變了1,_Deferred Implicit_將檢查全部5000個,_Deferred Explicit_將只檢查1你調用的'$ em-> persist()'。 –

0

你想實現的是所謂的部分更新。 你應該使用這樣的事情,而不是

/** 
* Partially updates an entity 
* 
* @param Object $entity The entity to update 
* @param Request $request 
*/ 
protected function partialUpdate($entity, $request) 
{ 
    $parameters = $request->request->all(); 

    $accessor = PropertyAccess::createPropertyAccessor(); 
    foreach ($parameters as $key => $parameter) { 
     $accessor->setValue($entity, $key, $parameter); 
    } 
} 

合併需要整個實體與數據fullfilled 100%。 我還沒有檢查兒童(多對一,一對一等)關係的行爲。

部分更新通常用於Rest API上的PATCH(或PUT)。