Propel ORM:在级联保存中重新触发发起的save()

时间:2012-07-27 19:10:32

标签: php propel

我有两个基于Propel的(Propel 1.6)模型类,FileUpload和Image:

<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>

当我实例化一个新的Image $图像,新的FileUpload $ upload,在$ image下注册$ upload然后尝试保存$ image希望级联保存$ image(第二个)和$ upload(第一个)...

$image = new Image();
$upload = new FileUpload();
// [set required properties in both models]
$image->setFileUpload( $image );
$image->save();

我收到外键违规错误:

  

无法执行UPDATE语句[UPDATE image SET FILE_UPLOAD_ID =:p1,UPDATED_AT =:p2 WHERE image.ID =:p3] [wrapped:SQLSTATE [23000]:Integrity约束违规:1452无法添加或更新子行:外键约束失败(DATABASENAMEimage,CONSTRAINT image_FK_1 FOREIGN KEY(file_upload_id)REFERENCES {{1} }(file_upload))]

我发现该错误是由于$ upload-&gt; save()调用了BaseFileUpload-&gt; doSave(),其中包括重新触发$ image-&gt; save():

id

...这意味着FileUpload镜像反对来自其他对象的反向引用,即使它本身只是引用,而不是引用其他任何对象。

当我覆盖Image-&gt; save()以首先清除链接的FileUpload上的所有镜像引用然后调用parent :: save()时,问题消失了:

if ($this->collImages !== null) {
  foreach ($this->collImages as $referrerFK) {
    if (!$referrerFK->isDeleted()) {
      $affectedRows += $referrerFK->save($con);
    }
  }
}

这种方法有效,但感觉很酷。它也可能只在这里使用,因为一旦保存$ upload对象,我就能轻松恢复外部引用 - 在其他情况下,它可能不那么简单。

是否有任何干净的方法可以防止从$ upload-&gt; save()重新触发$ image-&gt; save()的保存 - 而不会过多地干扰Propel的默认行为?感谢。

1 个答案:

答案 0 :(得分:2)

您可以在父对象(FileUpload)上调用save,并在将子对象添加到父对象并在父对象上调用save后保存子对象。

<?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

?>