我有兩個基於行走(推進1.6)模型類,文件上傳和圖像:的Propel ORM:原產保存()重新引發了級聯保存
<table name="file_upload">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="name" type="varchar" size="500" required="false" />
<column name="mime_type" type="varchar" size="100" required="true" />
<column name="data" type="blob" required="false" lazyLoad="true" />
</table>
<table name="image">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="file_upload_id" type="integer" required="true" />
<foreign-key foreignTable="file_upload" onDelete="restrict">
<reference local="file_upload_id" foreign="id" />
</foreign-key>
</table>
當我實例化一個新的圖像$形象,新文件上傳$上傳,註冊$在$圖片上傳,然後嘗試節省$圖像希望級聯保存這兩個$圖像(第二)和$上傳(第1號)...
$image = new Image();
$upload = new FileUpload();
// [set required properties in both models]
$image->setFileUpload($image);
$image->save();
我得到一個外鍵衝突錯誤:
Unable to execute UPDATE statement [UPDATE
image
SETFILE_UPLOAD_ID
=:p1,UPDATED_AT
=:p2 WHERE image.ID=:p3] [wrapped: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (DATABASENAME
.image
, CONSTRAINTimage_FK_1
FOREIGN KEY (file_upload_id
) REFERENCESfile_upload
(id
))]
我發現,錯誤造成的,因爲$ upload->保存()調用BaseFileUpload-> DoSave就會(),其中,除其他事項外,重新引發$圖像 - >保存():
if ($this->collImages !== null) {
foreach ($this->collImages as $referrerFK) {
if (!$referrerFK->isDeleted()) {
$affectedRows += $referrerFK->save($con);
}
}
}
...這意味着FileUpload鏡像從其他對象反向引用它,即使它本身只有引用,而不是引用別的。
當我重寫圖像 - >保存()首先清除所有鏡像上鍊接的FileUpload參考,然後調用父::保存(),問題解決了:
public function save(PropelPDO $con = null)
{
$upload = $this->getFileUpload();
if (null !== $upload && $upload->isModified()) {
$upload->clearAllReferences();
$upload->save($con);
$this->setFileUpload($upload);
}
return parent::save($con);
}
這種方法的作品,但感覺哈克。它只能在這裏使用,因爲一旦$ upload對象被保存,我就可以輕鬆地恢復外部引用 - 在其他情況下,它可能不那麼簡單。
有沒有乾淨的方法來防止從$ upload-> save()重新觸發$ image-> save()的保存 - 而不會干擾Propel的默認行爲太多?謝謝。