1. ホーム
  2. symfony

[解決済み] EntityManagerは終了しました。

2023-01-18 01:46:02

質問

[Doctrine\ORM\ORMException]   
The EntityManager is closed.  

データ挿入時にDBAL例外が発生した後、EntityManagerが終了してしまい、再接続ができません。

このようにやってみましたが、接続ができません。

$this->em->close();
$this->set('doctrine.orm.entity_manager', null);
$this->set('doctrine.orm.default_entity_manager', null);
$this->get('doctrine')->resetEntityManager();
$this->em = $this->get('doctrine')->getEntityManager();

どなたか再接続する方法をご存知ですか?

どのように解決するのですか?

少なくとも Symfony 2.0 と Doctrine 2.1 では、EntityManager を閉じた後に再び開くことができないので、これは非常にやっかいな問題です。

この問題を克服するために私が見つけた唯一の方法は、独自の DBAL 接続クラスを作り、Doctrine のものをラップし、例外処理 (たとえば EntityManager に例外を出す前に何度も再試行する) を提供することです。これは少し厄介で、トランザクション環境ではいくつかの矛盾を引き起こす可能性があります(つまり、失敗したクエリがトランザクションの途中にある場合に何が起こるかよくわかりません)。

この方法で行くための構成例を以下に示します。

doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        driver:   %database_driver%
        host:     %database_host%
        user:     %database_user%
        password: %database_password%
        charset:  %database_charset%
        wrapper_class: Your\DBAL\ReopeningConnectionWrapper

クラスは多かれ少なかれこのように始まるはずです。

namespace Your\DBAL;

class ReopeningConnectionWrapper extends Doctrine\DBAL\Connection {
  // ...
}

非常に厄介なのは、例外処理ラッパーを提供するConnectionの各メソッドをオーバーライドしなければならないことです。クロージャを使うことで、そこらへんの苦痛を軽減することができます。