Doctrine2无法插入数据

时间:2012-10-18 12:03:02

标签: php mysql insert doctrine-orm

我正在使用Doctrine,但是我第一次执行INSERT时无法persist/flush数据但是第二次工作,第3次失败:

// 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设置为全部,其他Doctrine和PHP问题,包括警告,会显示在日志中。)
- Doctrine SQLLogger没有显示任何内容(在第二次尝试时显示INSERT)。

一些故障排除步骤:
- 我希望通过使用DQL INSERT查询替换失败的尝试来进一步排查问题,但"INSERT statements are not allowed in DQL" :(
- 在失败尝试中实例化flush之前执行额外的$entity并不会有帮助 - 我可以手动将尽可能多的条目插入到数据库中,即使在第一次尝试时也能正常工作 - 我对2.4.0-DEV也有同样的问题 - 我对2.2.2也有同样的问题。

我可能会补充说,代码是在PHPunit测试中执行的,而在之前的测试中,我没有遇到问题(即Doctrine在第一个INSERT上正确执行了persist/flush 1}})。

知道问题可能来自哪里?

版本信息:
- PHP 5.4
- Doctrine 2.3.0pdo_mysql司机)
- MySQL 5.5.24
- Ubuntu 12.04
- PHPUnit 3.7.7

更新1:

好的,这是答案的一部分。问题似乎是我在PHPUnit setUp()中使用的例程在每次测试之间截断我的数据库表:

  • 如果我在每次测试之间截断我的表,我就会遇到问题(即某些INSERT失败)。
  • 如果我不截断,一切都会被罚款。

INSERT失败的方式似乎比最初想象的模式随机,因为我创建了2个测试,每个3个插入(并且只运行那些)。在每次测试之间截断表时,每次测试中的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();
}

我从this SO post获得了代码,据我所知,它看起来不错。如果我使用this other code

,我会遇到同样的问题
$connection = $entityManager->getConnection();
$platform   = $connection->getDatabasePlatform();
$connection->executeUpdate($platform->getTruncateTableSQL('my_table', true /* whether to cascade */));

我修改了我的架构以使用和不使用外键进行测试,我在两种情况下都有相同的问题。

1 个答案:

答案 0 :(得分:0)

最后看来问题发生在:
- 在setUp函数中的每个测试之间截断表格 AND
- 仅在setUpBeforeClass中实例化一次Doctrine实例(我之后使用self::$em访问)。

如果我在OR中实例化我的Doctrine实例,那么我不会在每个测试setUp之间截断表格,一切正常。

我曾经喜欢setUpBeforeClass,而不再是这样了......