2015-12-14 72 views
1

我正在尋找一種方法來將UnitOfWork返回到乾淨的狀態,而無需清除整個事物。我仍然想訪問我已經加載的實體。這是我所擁有的基礎,但我不確定這是否會以奇怪的方式打破主義。重置Doctrine中的所有UnitOfWork更改

$uow = $em->getUnitOfWork(); 
$uow->computeChangeSets();//Can this be called once here, or should it be called in the inside loop so we get fresh information after a potential cascading refresh or persist? 
foreach ($uow->getIdentityMap() as $className => $entities) { 
    foreach ($entities as $oid => $entity) { 
     if ($uow->isEntityScheduled($entity)) { 
      if ($uow->isScheduledForInsert($entity)) { 
       $uow->scheduleForDelete($entity);//Removes from the insert list without cascading delete or calling removal events 
      } elseif ($uow->isScheduledForUpdate($entity)) { 
       $em->refresh($entity); 
      } elseif ($uow->isScheduledForDelete($entity)) { 
       $em->persist($entity); 
       $em->refresh($entity);//Should I re-call computeChangeSets() here so I can check if the entity is now scheduled for update? 
      } 
     } 
    } 
} 

對於上下文:我正在運行一個批處理操作,其中每個記錄處理後都會持續進行所需的更改。如果一個記錄中的錯誤失敗,因爲,失敗是處理,但它可以用這種類型的異常打破批次的休息:

A new entity was found through the relationship FOO#bar that was not configured to cascade persist operations for entity: otherFooBar . 

因爲我並不需要從處理記錄保存更改如果失敗,我想簡單地清理所有更改並保持對象圖形不變,同時繼續處理批處理。

我已經閱讀了教條源,看起來這應該可以正常工作,但我對Doctrine的內部並不熟悉。有沒有人看到或知道這種方法的缺陷/陷阱或知道更好的方法來實現這一目標?

編輯:澄清這個問題背後的原因。

當處理記錄時發生錯誤時,這可能會使UoW/EntityManger處於不能被清除而不能保留的位置。在我的特殊情況下,錯誤留下了現有的已更改的實體,並且鏈接未保持實體的關係未配置爲級聯持久化,導致所有後續持久化失敗。此時,如果我想繼續處理批次並跳過失敗的記錄,我有兩個選擇:

1)清除EntityManager並從數據庫中重新加載所有業務邏輯實體。但這意味着恢復功能不能是通用的,必須定製以知道每次更改時要重新加載和調整哪些實體。

2)清潔使用的UnitOfWork的現有能力EntityManager的,這使得代碼是通用的,不需要進行持續改進。

回答

1

您在示例代碼中做什麼的問題是您正在使用標記爲內部的方法。這些並非真正用於「用戶區」代碼。如果你想安全地做到這一點,最好的辦法就是清理EntityManager並重新開始。

這就是說,你在做什麼看起來像應該工作。你不需要調用scheduleForDelete。只需調用預定要插入的實體的分離,它將從UnitOfWork中刪除。

+0

清除實體管理器的問題是我試圖從錯誤中恢復。有些實體在發生錯誤時加載,代碼仍然存在,並且不會從EntityManager中分離出來。我讀到的有關'computeChangeSets'的所有內容都表明,自己調用它會打破堅持的行爲。由於我試圖阻止圖中的任何新項目持續存在,這不是問題。 http://stackoverflow.com/a/16554133/1153227 – Omn

+0

我真的不明白你的使用情況。您是否嘗試處理Doctrine持續循環期間發生的錯誤,或者您是否正在處理應用中其他位置的錯誤? –

+0

我處理這使了EntityManager在所有未來持續,直到被清除會導致一個錯誤的狀態的非學說有關的錯誤。我已經編輯了我的問題,並進一步澄清了爲什麼我以這種方式解決問題。 – Omn