The EntityManager is closed

前端 未结 17 1644
星月不相逢
星月不相逢 2020-11-29 18:36
[Doctrine\\ORM\\ORMException]   
The EntityManager is closed.  

After I get a DBAL exception when inserting data, EntityManager closes and I\'m not

相关标签:
17条回答
  • 2020-11-29 18:55

    In Symfony 4.2+ you have to use the package:

    composer require symfony/proxy-manager-bridge
    

    otherwiese you get the exception:

    Resetting a non-lazy manager service is not supported. Declare the "doctrine.orm.default_entity_manager" service as lazy.  
    

    Than you can reset the entityManager like this:

    services.yaml:

    App\Foo:
        - '@doctrine.orm.entity_manager'
        - '@doctrine'
    

    Foo.php:

    use Doctrine\Bundle\DoctrineBundle\Registry;
    use Doctrine\DBAL\DBALException;
    use Doctrine\ORM\EntityManagerInterface;
    
    
     try {
        $this->entityManager->persist($entity);
        $this->entityManager->flush();
    } catch (DBALException $e) {
        if (!$this->entityManager->isOpen()) {
            $this->entityManager = $this->doctrine->resetManager();
        }
    }
    
    0 讨论(0)
  • 2020-11-29 18:56

    I faced the same problem. After looking at several places here is how I dealt with it.

    //function in some model/utility
    function someFunction($em){
        try{
            //code which may throw exception and lead to closing of entity manager
        }
        catch(Exception $e){
            //handle exception
            return false;
        }
        return true;
    }
    
    //in controller assuming entity manager is in $this->em 
    $result = someFunction($this->em);
    if(!$result){
        $this->getDoctrine()->resetEntityManager();
        $this->em = $this->getDoctrine()->getManager();
    }
    

    Hope this helps someone!

    0 讨论(0)
  • 2020-11-29 18:57

    Symfony v4.1.6

    Doctrine v2.9.0

    Process inserting duplicates in a repository

    1. Get access a registry in your repo
    
    
        //begin of repo
        
        /** @var RegistryInterface */
        protected $registry;
        
        public function __construct(RegistryInterface $registry)
        {
            $this->registry = $registry;
            parent::__construct($registry, YourEntity::class);
        }
    
    
    1. Wrap risky code into transaction and reset manager in case of exception
    
    
        //in repo method
        $em = $this->getEntityManager();
        
        $em->beginTransaction();
        try {
            $em->persist($yourEntityThatCanBeDuplicate);
            $em->flush();
            $em->commit();
        
        } catch (\Throwable $e) {
            //Rollback all nested transactions
            while ($em->getConnection()->getTransactionNestingLevel() > 0) {
                $em->rollback();
            }
            
            //Reset the default em
            if (!$em->isOpen()) {
                $this->registry->resetManager();
            }
        }
    
    
    0 讨论(0)
  • 2020-11-29 19:04

    Symfony 2.0:

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

    Symfony 2.1+:

    $em = $this->getDoctrine()->resetManager();
    
    0 讨论(0)
  • 2020-11-29 19:04

    You can reset your EM so

    // reset the EM and all aias
    $container = $this->container;
    $container->set('doctrine.orm.entity_manager', null);
    $container->set('doctrine.orm.default_entity_manager', null);
    // get a fresh EM
    $em = $this->getDoctrine()->getManager();
    
    0 讨论(0)
提交回复
热议问题