我在数据库中有以下结构:
在我的代码中,我首先创建一个公司,然后是一个日志,然后是一些日程表,然后是一个用户,然后是日志的责任。有点像这样(不是确切的简洁代码,但我认为认为很重要:
<?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();
}
即。如果我先手动保存它们而不是依赖级联。
答案 0 :(得分:2)
我无法直接回答您所看到的确切问题,但我在Propel中遇到了与外键和关系类似的混淆问题。我的最佳实践现在已成为手动设置ID,而不是允许Propel尝试管理通过定义的关系设置它们。在这种情况下,这意味着根本不会调用$logbookResponsibility->setLogbook()
或$logbookResponsibility->setUser()
。相反,请在$logbookResponsibility->setLogbookId()
和$logbookResponsibility->setUserId()
上致电save()
后致电$user
和$logbook
。
Propel通过引用做了很多事情,当你处理外键并通过调用期望对象的方法(例如setLogbook()
)而不是期望关系ID的方法来设置关系时,这会产生意想不到的后果(例如setLogbookId()
)。