2014-12-31 54 views
4

我有一個包含兩個生命週期事件方法的事件訂戶:prePersist和preUpdate。 prePersist之一按預期工作 - 我修改文檔,稍後在檢索文檔時反映這些更改。儘管如此,preUpdate沒有按預期工作。這基本上是什麼樣子:保留對Doctrine的PreUpdate生命週期事件對文檔所做的更改

/** 
* Also update the foo code when the bar profile is updated. 
* @param LifecycleEventArgs $args 
*/ 
public function preUpdate(LifecycleEventArgs $args) 
{ 
    $document = $args->getDocument(); 
    if ($document instanceof BarProfile) { 
     $document->setFooCode('Salamanders'); 
    } 
} 

如果我創建一個文檔,然後在perPersist功能設置其fooCode爲「佔位符」,然後當我檢索文件後,它fooCode是「佔位符」。如果我然後更新它,並再次檢索它,那麼我希望它的fooCode是'Salamanders'。但是,它仍然是'佔位符'。我甚至試過把error_log()的東西放在那裏,它會把東西寫到日誌中,這樣我就可以看到這個方法正在執行。

$document->setFooCode()之後,我需要做的第二步是讓fooCode的新值保持不變?

+1

閱讀細則和示例:http://doctrine-orm.readthedocs.org/en/latest/reference/events.html#preupdate。很多人都被這個問題絆倒了。 – Cerad

+0

我確實讀過......但我不明白這是什麼意思,直到下面的答案解釋它。 – beth

+0

我實際上最終在http://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/events.html#preupdate中使用瞭解決方案,因爲我無法識別我正在更改的屬性名稱在物體上。 – beth

回答

2

您不能直接在preUpdate事件中修改字段,您必須修改其原始值。不允許更改關聯。你必須做的:「在prePersist一個工作正常 - 我修改文檔,而當我檢索文件的更改後反映」

$eventArgs->setNewValue('fooCode', 'Salamanders'); 

你說

這使我相信你可能不知道持續和更新之間的區別。在Doctrine中,當您第一次創建對象時會出現持久性。當您對已經由Doctrine管理的現有對象進行更改時,會發生更新。很多人對此感到困惑,但在更新現有實體時,不需要撥打persist(),只需撥打flush()即可。例如:

// inserts a new entity into the database 
$document = new Document(); 
$document->setName('My Document'); 

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

// retrieves entity from the database, makes a change, then updates the database 
$document = $em->findOneByName('My Document'); 
$document->setFooCode('Salamanders'); 

$em->flush(); 

我鼓勵你read the Doctrine documentation喜歡CERAD建議。發揮密切注意下面的語句爲preUpdate事件:

  • 更新前的是最嚴格的使用事件
  • 更改更新實體協會在本次比賽中絕不允許
  • 更改領域的通過的實體不再被沖刷操作識別,使用傳遞給事件的計算的變更集來修改原始字段值
相關問題