私が使用していて、最初にデータDoctrine
に失敗しますが、2回目は機能し、3回目は失敗します:INSERT
persist/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 */));
外部キーの有無にかかわらずテストするようにスキーマを変更しましたが、どちらの場合も同じ問題があります。