2012-05-24 27 views
3

我正在構建一個訂單流程,其中一個Order對象是通過多個步驟構建的。在每一步之後,我將部分完成的Order對象放入session中,並在最後一步中將其保存到數據庫中。Doctrine2應自動合併關聯的實體

在這些步驟中,我將其他(已存在的)關聯對象加載到我的Order對象(例如DiscountCoupon)中。問題是,當我將Order保存到session,然後在下一步中加載它時,所有關聯的實體將被分離。所以當我想將它保存到數據庫時,EntityManager會引發異常,要求在關係上設置cascade=persist

當然,我不需要堅持這些對象(它們已經在數據庫中)。顯而易見的解決方案可能是將這些關聯的對象更改爲合併的對象(使用EntityManager#merge方法),但是,我有一個相當複雜的對象結構,其中包含多個嵌入實體級別,因此執行上述過程會很不方便。

Can not Doctrine能自動爲我完成這個任務嗎?所以不是對我分離的實體抱怨,它可以自動合併它們。

+0

我不知道學說,但:我可能不會在會話中存儲對象,以防萬一原則對象需要無法正確序列化的資源項目。我會將這些對象的主鍵存儲在會話中,因此當它們被檢索到時,您可以執行select操作 - 據推測在Doctrine中,您可以請求關聯的行自動加載它。 – halfer

+0

那麼,這可能是一個解決方案,但它會打破OO設計(我真的很討厭)。這樣我可以使用我稍後保存到數據庫中的相同實體對象。這些對象只存儲數據,其他實體對象和所有這些對象都可以被序列化。在訂購過程中,大多數對象都不在數據庫中(它們在流程中正確構建)。唯一的問題是,一旦保存到會話中並從會話中加載,數據庫中的項目就會分離。 –

+0

我敢打賭,分離效應是由於我提到的會話限制。我相信會有另一種基於對象的方式來做到這一點 - 只是必須重新創建每個頁面視圖中涉及的對象。 – halfer

回答

0

據我所知,如果你試圖使其完全自動化,你會創造一些嚴重的魔法。

最好的辦法是實現一個帶有簽名的函數:mergeOrderEntities($ Order,$ EntityManager),它知道如何在所有分離的關聯實體上說出Order結構並調用EntityManager :: merge()。

至於爲什麼主義不自動做到這一點,我不知道。我懷疑有些情況下自動合併實體可能是危險的,或者至少是不可取的。

+1

自動化可能是一種選擇。級聯屬性具有「合併」選項。 '@ORM \ OneToMany(targetEntity =「DiscountCoupon」,mappedBy =「order」,cascade = {「merge」})' 但它沒有幫助。它實際上做了什麼?文檔沒有提到這一點。 我想到的是創建一個函數遞歸遍歷一個對象併合並它找到的所有分離的實體。我只是不想重新發明輪子,所以我首先要問。 –

+0

我感覺你。這可能值得在郵件列表中詢問。 – timdev

+0

我問過它,並建議將表單數據存儲在會話中,所以我從每頁加載的表單數據構建Order對象。 –