[英]Doctrine 2 multi-level OneToOne Cascade
我有三個Doctrine實體:Device,它與Device \\ Status具有OneToOne關系,后者與Device \\ Status \\ Battery具有OneToOne關系。
我在相關實體之間設置了{cascade =“persist”},並且從我讀過的內容中,應該是Doctrine自動保存每個實體所需的全部內容,而無需在代碼中自行執行任何操作。
這是我遇到的問題:
$device = new \Entities\Device();
$device->setId(100);
$status = $device->getStatus();
$status->setIpAddress('192.168.0.1');
$battery = $status->getBattery();
$battery->setInternalLevel(60);
$em->persist($device);
$em->flush();
執行此代碼后,我收到以下錯誤:
Entity of type Device\Status\Battery has identity through a foreign entity
Device\Status, however this entity has no identity itself. You have to call
EntityManager#persist() on the related entity and make sure that an identifier
was generated before trying to persist 'Device\Status\Battery'. In case of
Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL)
this means you have to call EntityManager#flush() between both persist
operations.
我的問題是:設置我的實體以確保它們以正確的順序持續存在的正確方法是什么?
可以在此處找到實體的代碼: https : //gist.github.com/1753524
所有測試都是使用Doctrine 2.2沙箱進行的。
我認為@CappY是對的。
問題出在Status實體中。 當你執行getBattery()
並創建一個新的Battery實例時,它與你調用getBattery()
的Status實例有關。
由於該實例尚未存儲在數據庫中,因此尚未生成它的id(因為它的注釋為@GeneratedValue
)。 你對瀑布持續存在幾乎是正確的。 除了它在內存中執行。
所以,你需要堅持,做之前刷新狀態實體getBattery()
如果你想使用該實體作為電池ID。 或者你可以簡單地為電池添加一個id字段:)
您必須將cascade = {“persist”}添加到關系映射中。 您選擇的答案也是正確的但是使用該解決方案,如果在插入父數據后出現任何問題,則不會發生事務回滾。 您必須設置autocommit = false並手動執行提交事務。 使用cascade = {“persist”}你不必。 在數據庫操作期間出現任何問題,所有內容都將被回滾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.