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テーブルは 3 つの外部キーで構成され、それぞれに更新があります。RESTRICTただし、問題はカスケードの順序によって決まると思います。

部品を全部取り出せば$logbookResponsibility、完璧に動作します。の後$logbookResponsibilityパーツを配置して、同様に発行すると、それも完全に機能します。$user->save();$logbookResponsibility->save();

私の質問は、どこが間違っているのでしょうか? カスケードを機能させるために、私は何を間違っていると思いますか、または間違っていますか? それともそれを止めている可能性のある何か他のものがありますか?

更新:次のようにすると、問題なく動作します。

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

つまり、カスケードに頼るのではなく、最初に手動で保存した場合です。

4

1 に答える 1

2

あなたが見ている正確な問題に対して、適切で直接的な答えを提供することはできませんが、Propel の外部キーと関係で同様に混乱する問題に遭遇しました。私のベストプラクティスは、Propel が定義済みの関係を通じて ID の設定を管理しようとするのではなく、ID を手動で設定することになりました。この場合、それは電話をかけない、$logbookResponsibility->setLogbook()またはまったく電話しないことを意味$logbookResponsibility->setUser()します。代わりに、 and を呼び出した後にand$logbookResponsibility->setLogbookId()を呼び出します。$logbookResponsibility->setUserId()save()$user$logbook

Propel は参照によって多くのことを行います。これは、外部キーを扱ってsetLogbook()いて、関係の ID を期待するメソッド (例: ) ではなく、オブジェクトを期待するメソッド (例: ) を呼び出して関係を設定している場合に、意図しない結果をもたらす可能性がありますsetLogbookId()

于 2013-02-21T13:29:23.757 に答える