11

I have a console application with Symfony 2, the script run on cron (terminal). But, after \Doctrine\DBAL\DBALException the script throw N \Doctrine\ORM\ORMException with message "The EntityManager is closed.".

This is partial of script:

try {

    $this->getDoctrine()->getConnection()->beginTransaction();

    // ...

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

    $entity = new Post();
    $entity
        ->setAuthor($author)
        ->setTitle($title)
        ->setContent($content)
    ;

    $manager->persist($entity);
    $manager->flush();

    $this->getDoctrine()->getConnection()->commit();

    return $entity->getId();

} catch (\Doctrine\DBAL\DBALException $e) {

    $this->getDoctrine()->resetManager();

    $output->writeln(sprintf(
        '<error>[!] %s (%s) the post could not be created "%s"</error>',
        get_class($e),
        date('Y-m-d H:i:s'),
        $e->getMessage()
    ));

    return false;

} catch (\Exception $e) {

    $this->getDoctrine()->getConnection()->rollback();

    $output->writeln(sprintf(
        '<error>[!] %s (%s) the post could not be created "%s"</error>',
        get_class($e),
        date('Y-m-d H:i:s'),
        $e->getMessage()
    ));

    return false;
}

How to fix it?

João Paulo Cercal
  • 733
  • 1
  • 8
  • 12

3 Answers3

16

You can reset your entity manager manualy like this :

//...
} catch (\Doctrine\DBAL\DBALException $e) {

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

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

    $output->writeln(sprintf(
        '<error>[!] %s (%s) the post could not be created "%s"</error>',
        get_class($e),
        date('Y-m-d H:i:s'),
        $e->getMessage()
    ));

    return false;
} 
//...
j-guyon
  • 1,822
  • 1
  • 19
  • 31
2

On Symfony 5 I reopened connection in this way:

} catch (\Doctrine\DBAL\Driver\Exception $e) {
     /** @var \Doctrine\Persistence\ManagerRegistry $managerRegistry */
     $managerRegistry->resetManager();
} 

I have seen other cases where they use return value of resetManager(): ObjectManager as new entity manager instead of continuing using the same entity manager. But it is unnecessary, you can continue using the same entity manager.

Nuryagdy Mustapayev
  • 667
  • 1
  • 7
  • 27
  • it turns out to be necessary. they tend to remove things, like `em->refresh` i.o. adding them. I have a usecase for this: foreign component I cannot modify has memory leaks and manager reset saved my day. – Galvani Jul 07 '23 at 11:41
-3

If you use PSR-15 and PHP-DI in your project, try this middleware:

https://github.com/autorusltd/doctrine-persistent-entity-manager-middleware

You can use it like this:

use Arus\Middleware\DoctrinePersistentEntityManagerMiddleware;

$requestHandler->add(new DoctrinePersistentEntityManagerMiddleware($container));

$requestHandler->handle($request);