簡體   English   中英

Doctrine 2多級OneToOne Cascade

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM