2012-07-27 50 views
1

我有兩個基於行走(推進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 SET FILE_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 , CONSTRAINT image_FK_1 FOREIGN KEY (file_upload_id) REFERENCES file_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的默認行爲太多?謝謝。

回答

1

您可以調用保存父對象(FileUpload)和Propel保存子對象後,將它們添加到父級並調用保存父級。

<?php 
$upload = new FileUpload(); 
$image = new Image(); 
$image2 = new Image(); 

// set required fields on $upload, $image, and $image2 
// .... 

$upload->addImage($image); 
$upload->addImage($image2); 
$upload->save(); // save upload and new images 

?>