Не смотря на наличие
документации на которую сослался Денис Дерепко, она мало помогает в задаче подменить именно EntityManager, и именно когда к нему идет обращение в зависимостях через EntityManagerInterface.
По этому отдельным ответом пишу решение:
config/services.yaml:
App\Proxy\EntityManagerProxy:
decorates: 'doctrine.orm.entity_manager'
Proxy-обертка (здесь оставив за скобками почему в документации декоратор, а в моем случае proxy) с нужным функционалом - чтобы EntityManager переподключался в базе в случае потери соединения с базой (а доктрина закрывает соединение в случае любой SQL-ошибки):
class EntityManagerProxy implements EntityManagerInterface
{
private ObjectManager $entityManager;
private ManagerRegistry $doctrine;
public function __construct(ObjectManager $entityManager, ManagerRegistry $doctrine)
{
$this->entityManager = $entityManager;
$this->doctrine = $doctrine;
}
/**
* @param $object
* @return void
* @throws Exception
*/
public function persist($object): void
{
$this->correctionConnect();
$this->entityManager->persist($object);
}
/**
* @return void
* @throws Exception
*/
public function flush(): void
{
$this->correctionConnect();
$this->entityManager->flush();
}
private function correctionConnect(): void
{
// Для ошибок когда падает сама база или соединение с ней, например:
// SQLSTATE[57P01]: Admin shutdown: 7 FATAL: terminating connection due to administrator command
// SQLSTATE[08006] [7] could not translate host name "postgres" to address: Temporary failure in name resolution
// (например, когда на время падает контейнер с postgres)
if ($this->entityManager->getConnection()->ping() === false) {
$this->entityManager->getConnection()->close();
$this->entityManager->getConnection()->connect();
}
// Для ошибки "The EntityManager is closed" (например, при ошибки SQL-запроса)
if (!$this->entityManager->isOpen()) {
$this->doctrine->resetManager();
$this->entityManager = $this->doctrine->getManager();
}
}
// Все другие методы для EntityManagerInterface перебрасываются напрямую на базовый EntityManager