9

そのため、Doctrine2 を使用した整合性制約違反の後、EntityManager は、その EntityManager を使用し続けることを不可能にする方法で閉じるのが好きです。この単純な例外をキャッチして適切な方法で処理することを許可するのではなく、新しい EntityManager を作成する必要があるというのが一般的な考えのようです (素晴らしいデザイン / 皮肉)。

ただし、クローズド エンティティ マネージャで Bisna ライブラリ/ZF 1.12 を使用すると問題が発生します。Bisna ライブラリは、Container クラスで閉じられた後に同じ名前 (つまり「デフォルト」) で新しい EntityManager を作成する public メソッドを提供しません。

私の質問は、この問題に対処する最善の方法は何かということです。整合性制約違反の後に正常に回復する方法が必要です。

4

2 に答える 2

2

これらの状況から回復しようとする代わりに、整合性制約違反を防ぐことに集中する必要があります。

  • 外部キー制約にヒットした場合、エンティティを正しい方法で結び付けていません。
  • 一意の制約にヒットした場合は、データベースを永続化する前に重複データの可能性をチェックする必要があります。
  • 別のタイプの制約にぶつかり、それを防ぐ方法がわからない場合は、質問してください:)

アップデート:

Doctrine2 が EntityManager を閉じる理由は、ほとんどの場合、安全に使用できなくなったためです。その UnitOfWork には、実行できない操作が含まれています (したがって、例外がスローされます)。

Bisna ライブラリが新しい EntityManager の作成をサポートしていないことは正しいです。このような機能を自分で実装するために拡張できます。

別の解決策は、トランザクションを手動で処理することです。

$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
    // do some work
    $user = new User;
    $user->setName('George');
    $em->persist($user);
    $em->flush();
    $em->getConnection()->commit();
} catch (Exception $e) {
    $em->getConnection()->rollback();
    $em->clear();  // in stead of $em->close();
    throw $e;
}

に置き換えること$em->close()$em->clear()、EntityManager を開いたままにして、再び使用できるようにします。

EntityManager 内のデータは (ほとんどの場合) 使用できなくなるため、EntityManager を閉じるクリアすることを強くお勧めします。

于 2013-03-26T09:20:01.090 に答える