我有一个Laravel应用程序,它运行'swooletw/laravel-swoole‘来处理请求。Doctrine使用laravel-doctrine/orm作为对象关系映射。
通常,如果某个ORMException被抛出,它会关闭EntityManager,该the应该在下一次请求时自动打开/重置。但是,当我使用swoole时,它不会简单地发生,除非重新启动swoole worker,否则EntityManager将保持关闭状态。
我试图通过检查entitmanager是否关闭并在中间件中将其重置来修复此问题。因此,在下一个请求中,它应该提供一个新的实体管理器。
protected function handleClosedManagers()
{
foreach (Registry::getManagerNames() as $managerName) {
/** @var EntityManager $manager */
$manager = Registry::getManager($managerName);
if (!$manager->isOpen()) {
Registry::resetManager($managerName);
$manager = Registry::getManager($managerName);
}
}
}理想情况下,它应该可以解决这个问题,但我得到的结果是"EntityManager is Closed“。异常。
我假设我也需要从laravel容器中刷新它。
所以我把代码改成这样:
protected function handleClosedManagers()
{
foreach (Registry::getManagerNames() as $managerName) {
/** @var EntityManager $manager */
$manager = Registry::getManager($managerName);
if (!$manager->isOpen()) {
Registry::resetManager($managerName);
$manager = Registry::getManager($managerName);
app()->forgetInstance('doctrine.managers.'.$managerName);
app()->forgetInstance('mem');
app()->forgetInstance(MagentoEntityManager::class);
app()->singleton('doctrine.managers.'.$managerName, function () use ($manager) {
return $manager;
});
// we are using separate entitymanager than default one
app()->singleton('mem', function () use ($manager) {
return $manager;
});
}
}
}现在我把这个放在persist上:
ErrorException: Undefined index: 000000005ba55063000000001b2f101d in file /***/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 3003
有人知道处理这种情况的正确方法吗?
发布于 2019-09-06 03:50:26
我在Zend Expressive应用程序中遇到了同样的问题。
我发现,通过将Entity Manager包装到一个装饰器中,可以在需要时用新的实例替换实际的Entity Manager,而不是尝试在容器和所有可以注入它的服务中替换关闭的Entity Manager,而是使Entity Manager更容易重置:
final class ResettableEntityManager extends \Doctrine\ORM\Decorator\EntityManagerDecorator
{
/**
* @var callable
*/
private $entityManagerFactory;
public function __construct(callable $entityManagerFactory)
{
$this->entityManagerFactory = $entityManagerFactory;
parent::__construct($entityManagerFactory());
}
public function recreate(): void
{
$this->wrapped = ($this->entityManagerFactory)();
}
}在每个请求的末尾,如果Entity Manager关闭,我会重新创建它,否则我只是将其清除以防止内存泄漏:
if ($this->entityManager->isOpen()) {
$this->entityManager->clear();
} else {
$this->entityManager->recreate();
}https://stackoverflow.com/questions/57104356
复制相似问题