Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 2.6/Doctrine ORMException: The EntityManager is closed

I am importing users from an excel file. I have created entity manager:

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

This is my loop:

...
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();
}
...
  • Email field is unique in db and I do not want to check duplicate before flush (db validation)
  • I want to flush one by one for log reasons (not batch insert).
  • All my other codes and files (entity, services, configurations, ...) are correct and has no errors.

The first problem is if one of the rows has an email that exist in db (duplicate), the loop breaks by an exception from db. I have solved the problem with this simple change:

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

The next problem is the "The EntityManager is closed" exception. If one email is duplicate, EntityManager ($em) will close automatically. I have solved this by creating the $em before try/catch:

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

Everything is OK. But I have a big problem with adding the channel to user:

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

$channel is not a new one. But after closing and creating the EntityManager, the system thinks it is new on line persist (The $channel will successfully add if there is no errors):

ORMInvalidArgumentException {#1400 ▼
  #message: "A new entity was found through the relationship 'My\UserBundle\Entity\User#channels' that was not configured to cascade persist operations for entity: My\PostBundle\Entity\Channel@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 'My\PostBundle\Entity\Channel#__toString()' to get a clue."
  #code: 0
  #file: "...\vendor\doctrine\orm\lib\Doctrine\ORM\ORMInvalidArgumentException.php"
  #line: 91
  -trace: array:13 [▶]
}

All my problems are from recreating EntityManager. I think its a bug. Validating data in database side (Unique, Null, Foreign Keys, ...) is common. Closing the EntityManager after db errors means we can not communicate with db after any error.

I have 2 questions:

  1. Is there any way to prevent EntityManager close?!
  2. Can I use DBAL Doctrine to import my users? (users may have duplicated emails)
like image 504
Mahmood Feiz Avatar asked Feb 16 '26 23:02

Mahmood Feiz


1 Answers

Exceptions are for exceptional situations. They're designed to let you clean up and then return a friendly error. They're not designed for validation.

How you're using them here is to say "Is it possible to add this user?" and if not, restart the database. That is, stop the entity manager manager from throwing exceptions, instead of trying to carry on after it has thrown an exception.

So if you've identified that the entity manager is throwing an exception and closing when you try to add a duplicate user, then check whether the user is a duplicate before trying to add them.

However, you said above that you don't want to use this approach. In that case, you will need to write your own SQL queries and can use DBAL (or just raw PDOs) and handle the SQL responses yourself.

like image 79
Dan Blows Avatar answered Feb 18 '26 12:02

Dan Blows



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!