5

私が使用していて、最初にデータDoctrineに失敗しますが、2回目は機能し、3回目は失敗します:INSERTpersist/flush

// there is no code executed between any of the attempts

$entity = new My\Entity();
$entity->setTag('A');  // just a random field
$em->persist($entity);
$em->flush();
// INSERT not performed
// if I exit here and check the database, no entry is added

$entity = new My\Entity();
$entity->setTag('B');
$em->persist($entity);
$em->flush();
// INSERT performed
// if I exit here and check the database, 1 entry has been added
// and I can see it's "B"

$entity = new My\Entity();
$entity->setTag('C');
$em->persist($entity);
$em->flush();
// INSERT not performed
// if I exit here and check the database, there is still only 1 entry added
// and I can see it's "B"

失敗した試行で気づいたことは次のとおりです:
- には何もありませんPHP logs(error_reportingは all に設定されており、警告を含むその他の Doctrine および PHP の問題がログに表示されます)。
-Doctrine SQLLoggerは何も表示しません (2 回目の試行では が表示されますINSERT)。

いくつかのトラブルシューティング手順: - 失敗した試行をクエリ
に置き換えてさらにトラブルシューティングしたかったのですが、 「INSERT ステートメントは DQL では許可されていません」 :( - 失敗した試行でインスタンス化する前に 追加を実行しても役に立ちません - いくつでも挿入できますエントリをデータベースに手動で追加すると、最初の試行でも機能します。 - で同じ問題があります。 - で同じ問題があります。DQL INSERT
flush$entity
2.4.0-DEV
2.2.2

コードがPHPunitテスト内で実行され、以前のテストでは問題が発生していないことを追加する場合があります (つまり、Doctrine はINSERT最初の を適切に実行しますpersist/flush)。

問題の原因はどこにあるのでしょうか?

バージョン情報:
- PHP 5.4
- Doctrine 2.3.0(pdo_mysqlドライバー)
- MySQL 5.5.24
- Ubuntu 12.04
-PHPUnit 3.7.7

更新 1:

わかりました、これは答えの一部です。PHPUnit setUp()問題は、各テスト間でデータベース テーブルを切り捨てるために使用するルーチンによるようです。

  • 各テスト間でテーブルを切り捨てると、問題が発生します (つまり、INSERT失敗するものもあります)。
  • 切り捨てなければ、すべてうまくいきます。

それぞれ 3 つの挿入の 2 つのテストを作成した (そしてそれらのみを実行した)ため、s が失敗する方法はINSERT、最初に考えられていたよりもランダムなモードのようです。各テスト間でテーブルを切り捨てる場合、各テストの 3 つの挿入は次のようになります: -テスト
1: 成功 / 成功 / 成功 -テスト
2: 成功 / 成功 / 失敗慣れている)。

テーブルを切り捨てるために使用しているコードは次のとおりです。

$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$dbPlatform = $connection->getDatabasePlatform();
$connection->beginTransaction();
try {
    $connection->query('SET FOREIGN_KEY_CHECKS=0');
    $q = $dbPlatform->getTruncateTableSql($cmd->getTableName());
    $connection->executeUpdate($q);
    $connection->query('SET FOREIGN_KEY_CHECKS=1');
    $connection->commit();
}
catch (\Exception $e) {
    $connection->rollback();
}

この SO 投稿からコードを取得しましたが、見た限りでは良さそうです。この他のコードを使用すると、同じ問題が発生します。

$connection = $entityManager->getConnection();
$platform   = $connection->getDatabasePlatform();
$connection->executeUpdate($platform->getTruncateTableSQL('my_table', true /* whether to cascade */));

外部キーの有無にかかわらずテストするようにスキーマを変更しましたが、どちらの場合も同じ問題があります。

4

1 に答える 1

0

最終的に、この問題は次の場合に発生したようです: -関数
内の各テスト間でテーブルを切り捨てるsetUp
AND
- Doctrine インスタンスを 1 回だけインスタンス化しますsetUpBeforeClass(そのときは でアクセスしていましたself::$em)。

ORで Doctrine インスタンスをインスタンス化する場合、各テスト間でテーブルを切り捨てなければsetUp、すべて正常に動作します。

以前は が好きでしたsetUpBeforeClassが、もうそうではありません...

于 2012-10-18T13:53:23.140 に答える