2011-10-11 53 views
6

我使用的是Doctrine 2實體。我們有一些實體在將其保存到數據庫時必須更新相關項目。例如,當用戶記錄被修改時,我們將其保存爲新記錄,並將「非活動」字段設置爲「假」。但是,我們必須將該用戶的所有先前記錄的「非活動」字段設置爲「真」。這樣做是爲了保留審計歷史。這是一個傳統數據庫,所以更改結構不是一個選項。由於Doctrine通過將對象傳遞給persist對象(persist ::($ thisObj))來保存對象,而不是具有保存方法的對象($thisObj->save()),所以我們不能只從一個保存方法父對象。我在這裏看到的唯一選擇是試圖擴展'堅持'的對象,但這聽起來像一隻鵝羣,只是等待發生。學說2,需要執行代碼前持久性/後持久性

我發現了一些有關事件的信息,但沒有看到如何添加它們以使事件在特定實體持續存在時觸發特定函數。

如何向我的某些實體添加預保存/保存後功能?

回答

12

那麼,你可能已經知道http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html對不對?

您添加的實體包含回調的註解,然後創建該實體特定功能(這需要公開),並與@PrePersist或@PostPersist或任何註釋它們。所謂prePersist,postPersist等

另一種方法是創建一個事件訂閱,註冊一個與教義事件管理和實施方法,他們獲得通過的EventArguments對象包含了有關所發生的事件的實體。

我知道這是對您的問題的一個非常普遍的答案,但您需要針對問題所在的位置進行更具體的解答。

請不要發放實體管理器並覆蓋堅持的方法,有很多方法可以做到你所需要的更清晰的方法,據我所知。

7

這實際上很簡單,做你想做的事情。它不需要與活動經理或任何類似的複雜活動。你使用了一種叫做「生命週期回調」的東西。這些函數主義的實體的「生命週期」過程中自動運行,即:prePersist,postPersist,更新前,postUpdate等,您可以在這裏找到完整的列表:http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html

添加此功能,您的實體的過程非常簡單。

  1. 在你的實體的註釋部分,包括以下標籤:「@HasLifecycleCallbacks」。這告訴Doctrine它應該搜索實體以便在各種事件中運行功能
  2. 在您的實體中編寫一個公用函數,您想在特定事件上觸發該函數。
  3. 將一個註釋放在函數的上方,指出應該使用哪個事件來處理。

例如,看一下下面的代碼:

/** @PostPersist */ 
public function doSPostPersist() { 
    $this->tester = 'Value changed by post-persist'; 
} 

我發現,有時候事件索性不火了,我還不知道是什麼原因。但是當他們開火時,他們會可靠地射擊。

+2

OK,想通了,爲什麼事件有時「乾脆拒絕解僱」。 prePersist/posPersist事件僅在保存新記錄時纔會發生。如果您正在更新現有記錄,則preUPdate/postUpdate會消失。因此,即使調用持久化方法,如果要保存現有對象,也應用preUpdate/postUpdate生命週期事件。 –

+0

感謝您帶領我走向正確的方向。一個後續行動:我從基礎類中獲取所有實體,以提供一些常規功能。我討厭必須在每個實體中放置一個事件,因爲在我的情況下,我真的只是使用postLoad來激發構造函數,並且我希望在所有實體中都這樣做。有什麼辦法可以將它移到基類中,而無需在entitiy中進行額外的複製和粘貼? – redreinard

+0

第二點對我來說非常有用!非常感謝你! –

2

不要忘記啓用生命週期回調在你的類註釋:

/** 
* Report\MainBundle\Entity\Serveur 
* @ORM\HasLifecycleCallbacks 
*/ 
class Serveur { 
+0

是否需要「ORM \」部分?沒有它,它似乎可以很好地工作,但我想用最好的做法。 – redreinard

+0

這不是最佳實踐,只是映射管理器的別名,使用Doctrine \ ORM \ Mapping作爲ORM; ... /** * @ORM \ HasLifecycleCallbacks * / – ROLO