2

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

在此处输入图像描述

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

<?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();然后再发出 a $logbookResponsibility->save();,那也很有效。

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

更新:如果我执行以下操作,它工作得很好:

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

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

4

1 回答 1

2

对于您所看到的确切问题,我无法给您一个好的、直接的答案,但是我在 Propel 中遇到了与外键和关系类似的令人困惑的问题。我现在的最佳实践是手动设置 ID,而不是让 Propel 尝试通过定义的关系来管理设置它们。在这种情况下,这意味着不打电话$logbookResponsibility->setLogbook()或根本不打电话$logbookResponsibility->setUser()。而是在调用and$logbookResponsibility->setLogbookId()之后$logbookResponsibility->setUserId()调用and 。save()$user$logbook

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

于 2013-02-21T13:29:23.757 回答