Symfony 2.6/Doctrine ORMException: The EntityManager is clos



我正在从excel文件导入用户。我创建了实体经理:

$em = $this->getDoctrine()->getManager();

这是我的循环:

...
for ($i=2; $i<=count($usersdatas); $i++) { // $userdatas: an array of users imported from excel
    $nuser = new User();
    $nuser->setEmail($usersdatas[$i]['A']); // email is unique in db
    $nuser->setFname($usersdatas[$i]['B']);
    $nuser->setLname($usersdatas[$i]['C']);
    $nuser->addChannel($channel); //ManytoMany relation
    $em->persist($nuser);
    $em->flush();
}
...
  • 电子邮件字段在数据库中是唯一的,我不想在刷新前检查重复项(数据库验证)
  • 由于日志原因,我想逐个刷新(而不是批量插入)
  • 我的所有其他代码和文件(实体、服务、配置…)都是正确的,没有错误

第一个问题是,如果其中一行的电子邮件存在于数据库中(重复),则循环会被数据库中的异常打断。我用这个简单的改变解决了这个问题:

...
try {
    $em->persist($nuser);
    $em->flush();
} catch (Exception $e) {
    ...
}
...

下一个问题是"EntityManager已关闭"异常。如果一封电子邮件重复,EntityManager($em)将自动关闭。我已经通过在try/catch之前创建$em解决了这个问题:

...
if (!$em->isOpen()) {
    $em = $em->create(
    $em->getConnection(), $em->getConfiguration());
}
...

一切都很好。但我有一个大问题,添加信道到用户:

...
$nuser->addChannel($channel); //ManytoMany relation
...

$channel不是一个新频道。但在关闭并创建EntityManager后,系统认为它是新的在线持久化(如果没有错误,$channel将成功添加):

ORMInvalidArgumentException {#1400 ▼
  #message: "A new entity was found through the relationship 'MyUserBundleEntityUser#channels' that was not configured to cascade persist operations for entity: MyPostBundleEntityChannel@000000002768057d0000000046371762. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'MyPostBundleEntityChannel#__toString()' to get a clue."
  #code: 0
  #file: "...vendordoctrineormlibDoctrineORMORMInvalidArgumentException.php"
  #line: 91
  -trace: array:13 [▶]
}

我所有的问题都来自于重新创建EntityManager。我认为这是个错误。验证数据库端的数据(唯一、Null、外键…)是常见的。在数据库出现错误后关闭EntityManager意味着我们在出现任何错误后都无法与数据库通信。

我有两个问题:

  1. 有什么方法可以阻止EntityManager关闭吗
  2. 我可以使用DBAL原则导入我的用户吗?(用户可能有重复的电子邮件)

异常适用于特殊情况。它们的设计目的是让你清理,然后返回一个友好的错误。它们不是为验证而设计的。

你在这里使用它们的方式是说"有可能添加这个用户吗?"如果没有,请重新启动数据库。也就是说,阻止实体管理器管理器抛出异常,而不是在抛出异常后继续执行。

因此,如果您在尝试添加重复用户时发现实体管理器正在抛出异常并关闭,请在尝试添加用户之前检查该用户是否为重复用户。

但是,您在上面说过,您不想使用这种方法。在这种情况下,您将需要编写自己的SQL查询,并且可以使用DBAL(或仅使用原始PDO)并自己处理SQL响应。

相关内容

  • 没有找到相关文章

最新更新