为什么我的推进级联被外键约束阻挡?

时间:2013-02-21 13:17:43

标签: php foreign-keys constraints propel cascade

我在数据库中有以下结构:

enter image description here

在我的代码中,我首先创建一个公司,然后是一个日志,然后是一些日程表,然后是一个用户,然后是日志的责任。有点像这样(不是确切的简洁代码,但我认为认为很重要:

<?php

$company = new Company();
$company->setSomething(123);

$logbook = new Logbook();
$logbook->setSomething('abc');
$logbook->setCompany($company);

$schedules = array();
for ($x=0; $x<$something; $x++) {
  $schedule = new Schedule();
  $schedule->setSomething(doSomethingWithSomething($something[$x]);
  $schedule->setLogbook($logbook);
  $schedules[] = $schedule;
}

$user = new User();
$user->setSomething('something');
$user->setCompany($company);
$user->setCurrentLogbook($logbook);

$logbookResponsibility = new LogbookResponsibility();
$logbookResponsibility->setLogbook($logbook);
$logbookResponsibility->setResponsibilityId(1);
$logbookResponsibility->setUser($user);

$errors = someFormOfCheck();

if (!$errors) {
  $user->save();
  $logbookResponsibility->save();
  foreach ($schedules as $schedule) {
    $schedule->save();
  }
}

我收到以下错误:

<b>Fatal error</b>:  Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`logbook`.`logbook_responsibility`, CONSTRAINT `fk_logbook_responsbility_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE)' in C:\wamp\bin\php\php5.3.8\pear\propel\connection\DebugPDOStatement.php:90

logbook_responsibility表由三个外键组成,每个外键在更新上都有RESTRICT,因为我不希望它可以删除用户,日志或类型责任是否存在日志责任。但我认为问题是由级联的顺序决定的。

如果我完全取出$logbookResponsibility部分,那就完美了。如果我将$logbookResponsibility部分放在之后$user->save();,然后再发出$logbookResponsibility->save();,那也很有效。

那么,我的问题是我哪里出错了?为了使级联工作,我认为是不正确或做错了什么?或者还有什么东西可能阻止它?

更新:如果我执行以下操作,它就可以正常运行:

$company->save();
$logbook->save();
$user->save();
$logbookResponsibility->save();
foreach ($schedules as $scheudle) {
  $schedule->save();
}

即。如果我先手动保存它们而不是依赖级联。

1 个答案:

答案 0 :(得分:2)

我无法直接回答您所看到的确切问题,但我在Propel中遇到了与外键和关系类似的混淆问题。我的最佳实践现在已成为手动设置ID,而不是允许Propel尝试管理通过定义的关系设置它们。在这种情况下,这意味着根本不会调用$logbookResponsibility->setLogbook()$logbookResponsibility->setUser()。相反,请在$logbookResponsibility->setLogbookId()$logbookResponsibility->setUserId()上致电save()后致电$user$logbook

Propel通过引用做了很多事情,当你处理外键并通过调用期望对象的方法(例如setLogbook())而不是期望关系ID的方法来设置关系时,这会产生意想不到的后果(例如setLogbookId())。