У меня есть приложение, работающее с Symfony 3.4 с MySql, и я получаю сообщение об ошибке: "EntityManager закрыт". Мое приложение работает двумя способами:
1 - Консольное приложение, которое каждый раз вызывается скриптом sh. Это консольное приложение делает много вставок в таблице базы данных.
2 - Маршрут HTTP, который также вставляется в ту же таблицу.
Когда консольное приложение работает в фоновом режиме, если я вызываю маршрут http, я получаю сообщение об ошибке "EntityManager закрыт". Если я остановлю приложение backgroud, то работает http-маршрут. Как будто обе консоли приложений и http используют один и тот же экземпляр EntityManager.
Мой код:
Я создаю службу под названием AbstractRepositoryService. Все мои службы, которые управляют репозиториями, должны расширяться.
<?php
abstract class AbstractRepositoryService
{
/**
*
* @var EntityManagerIntergace - $em
*/
protected $em;
/**
*
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em) {
$this->em = $em;
}
/**
*
*
* @param String
*
* @return @mixed
*
* @throws RuntimeException
*/
public function __call($method, $args) {
$repository = $this->em->getRepository(static::ENTITY);
if (!method_exists($repository, $method)) {
throw new RuntimeException(
sprintf("Method '%s' not found.", $method),
500
);
}
try {
return call_user_func_array(array($repository, $method), $args);
} catch(Exception $e) {
throw new Exception($e->getMessage(), 500);
}
}
}
Мой UserRepositoryService, где исключение выбрано методом flush
<?php
final class UserRepositoryService extends AbstractRepositoryService
{
/**
*
* @const String
*/
const ENTITY = 'AppBundle\\Entity\\User';
/**
*
* @param User
*/
public function insert(User $user) {
try {
$this->em->persist($user);
$this->em->flush($user);
} catch (Exception $e) {
throw new Exception($e->getMessage(), 500);
}
}
}
И завершите мою служебную декларацию:
app.services.user_repository_service:
public: true
class: AppBundle\Services\UserRepositoryService
arguments:
- '@doctrine.orm.entity_manager'
Решено!
Я создал метод, который генерирует новый EntityManager перед вставкой и работает сейчас.
protected function createNewEntityManager() {
return $this->em->create(
$this->em->getConnection(),
$this->em->getConfiguration(),
$this->em->getEventManager()
);
}
И вставить:
public function insert(Crawler $crawler) {
try {
$this->createNewEntityManager();
$this->em->persist($crawler);
$this->em->flush($crawler);
$this->em->close();
} catch (Exception $e) {
throw new Exception($e->getMessage(), 500);
}
}