2013-12-12 17 views
0

我有一個Person是多到一用一Family。該系統同時接納多行數據與多個人,這些數據可能屬於同一家庭,也可能不屬於同一家族。我事先沒有關於家庭的信息。在哪裏可以在EntityRepository可以訪問的Zend中放置預刷新的實體狀態數據?

當我處理Person進入系統時,我檢查是否需要先將它的Family添加到數據庫中。我很自然地問,從FamilyRepository,但即使我已經創建並堅持同Family,該FamilyRepository仍然不知道這一點,因爲它只能在flush()寫入到數據庫中。

的解決辦法是暫時新建FamilyPrePersist過程中參考地方添加,並從那個地方,以及從數據庫中FamilyRepository檢查。

但是在哪裏應該暫時保留但尚未刷新的實體引用go,以便我可以從實體的存儲庫中訪問它?

替代方案,我不喜歡:

  • ,做的代碼添加(PersonService->insertPersons())當然可以跟蹤堅持的實體,但是這似乎是一個非最佳的解決方案,因爲它是不是一個通用的解決方案,代碼將不得不放在添加數據的每個地方。

  • 我可以沖水每次加入後,但我寧願不刷新,直到所有的數據已被處理。

  • could也通過$entityManager->getUnitOfWork()->getScheduledEntityInsertions()循環,並從那裏找到條目,但這似乎更像是一種實際解決方案的破解。

+0

你不妨來看看這個問題:http://stackoverflow.com/questions/7877987/read-objects-persisted-but-not-yet-flushed-with-doctrine – netiul

+0

@netiul感謝您的相關鏈接。儘管如此,我不認爲這些答案對我的問題有解決方案。我想我可以循環訪問'getScheduledEntityInsertions()',但這看起來更像是一種破解 - 我編輯了這個問題來包含這個。 PatrikAkerstrand的答案是有道理的,但它需要相當大的重構來爲所有實體使用自定義引用對象(此外,實體管理器應該做的事情並不是那麼令人興奮)。 –

回答

2

我不是你想要做什麼完全清楚,但它聽起來像是你可以通過手動處理您的交易(假設你使用ORM,反正處理這個問題。不知道有關事務支持ODM)。

通過在一個事務中包裝你的整個導入,可以使增量刷新,使得由倉庫發出的SELECT將返回數據,但你仍然可以回滾整個事情,如果出現錯誤:

<?php 

$em->beginTransaction(); 
$familyRepository = $em->getRepository('Family'); 

foreach($personData as $p){ 
    $lastname = $p['lastname']; 

    $person = new Person(); 
    $person->setLastname($lastname); 

    $family = $familyRepository->findOneByLastname($lastname); 

    if (! $family){ 
     $family = new Family(); 
     $family->setLastname($lastname); 
     $em->persist($family); 
    } 

    $person->setFamily($family); 
    $em->persist($person); 
    $em->flush(); 
} 
$em->commit(); 
+0

嗯,你是對的,事務回滾確實達到與不沖洗相同的結果。我想這個問題可能是我對整個刷新概念感到困惑 - 我曾經覺得它可以像交易一樣使用,爲持久層提供「好,我完成了」的信號。但我想這可能只是意味着更短暫,留下「好的,我完成了」交易。 –

+0

這真的取決於你的用例。我發現隨着時間的推移,我傾向於自己處理交易劃分。這對於測試也非常方便,因爲你可以在開發的時候s/commit()/ rollback /並且觀察你的mysql查詢日誌來看看底層是什麼原則。當手動處理事務時,flush()只是將查詢發送到數據庫,但是由於START TRANSACTION發生了,直到您顯式調用commit()時纔會提交它們。 – timdev

+0

是的,它對調試奇怪的學說行爲非常有用。儘管如此,我仍然無法動搖這種有點冒失和錯誤的解決方案。 db持久層的要點在於當代碼在內存中,db在數據庫中,或者它們在事務中時(除非它是一個關鍵的原子操作),代碼在理論上應該不在意。但也許這只是我個人的問題。 :) –

相關問題