我的自定义Doctrine2存储库存在一个奇怪的问题。
我有一个DELETE控制器,看起来基本上是这样的:
public function deleteAction(MyEntity $myEntity, MyEntityRepository $myEntityRepository)
{
$myEntityRepository->remove($myEntity);
$myEntityRepository->flushEntityManager();
return new JsonResponse(['message' => 'Bye bye!']);
}
Repository的remove方法如下所示:
public function remove(MyEntity $entity): MyEntityRepository
{
$this->getEntityManager()->remove($entity);
return $this;
}
之前已经有效,但现在,我得到了一个例外:
无法删除已分离的实体AppBundle \ Entity \ MyEntity @ 000000003b458c32000000007fd2994a
我真的不知道,为什么Repository中的EntityManager认为,实体是分离的。当我将EntityManager直接注入我的控制器时,一切正常:
public function deleteAction(MyEntity $myEntity, EntityManagerInterface $em)
{
$em->remove($myEntity);
$em->flush();
return new JsonResponse(['message' => 'Bye bye!']);
}
有关于此的任何想法吗?为什么我从Doctrine \ ORM \ EntityRepository-> getEntityManager()获取的EntityManager与注入我的控制器的EntityManager不同?
P.S。我的其他DELETE操作没有这个问题,他们都使用相同的自定义存储库。这让我很疯狂。
编辑:在存储库中转储$this->getEntityManager()
出现:
EntityManager {#627 ▼
-config: Configuration {#461 ▶}
-conn: Connection {#471 ▶}
-metadataFactory: ClassMetadataFactory {#618 ▶}
-unitOfWork: UnitOfWork {#493 ▶}
-eventManager: ContainerAwareEventManager {#511 ▶}
-proxyFactory: ProxyFactory {#588 ▶}
-repositoryFactory: DefaultRepositoryFactory {#619 ▶}
-expressionBuilder: null
-closed: false
-filterCollection: FilterCollection {#598 ▶}
-cache: null
}
在控制器内转储$em
时会出现
DoctrineORMEntityManager_00000000644c03b80000000000dac8cc6811571fd60520ff7ea135d840b51abe {#410 ▼
-valueHolder59cfe1676bb7b138763071: EntityManager {#664 …11}
-initializer59cfe1676bb84613288121: null
}
答案 0 :(得分:2)
我创建了一个新的空Symfony项目,以逐步重现问题。我得到了同样的错误,当我实现我的实体监听器时,它有一个辅助类作为依赖,它本身有MyEntityRepository作为依赖。删除此依赖项消除了分离的实体的问题。
稍后进一步调查,我意识到,注入的EntityManager实例有时是新实例。要获取注入的主实例(并按顺序删除循环引用错误),您可以将实体侦听器服务标记为延迟:
AppBundle\EventListener\MyEntityListener:
autowire: true
autoconfigure: true
# the service must be public, when it's tagged lazy
public: true
tags:
- { name: doctrine.orm.entity_listener, lazy: true }
这种懒惰的东西解决了我的问题!
但我仍然不明白,为什么我将另一个EntityManager实例注入我的存储库,当另一个服务注入此存储库时。
对于记录,MyEntityRepository配置:
AppBundle\Entity\Repository\MyEntityRepository:
autowire: false
autoconfigure: true
public: false
factory: ['@doctrine.orm.default_entity_manager', getRepository]
arguments:
- AppBundle\Entity\MyEntity
listerner服务:
class MyEntityListener
{
/** @var MyEntityHelper */
protected $myEntityHelper;
public function __construct(MyEntityHelper $myEntityHelper)
{
$this->myEntityHelper = $myEntityHelper;
}
// ...
}
和帮助服务:
class MyEntityHelper
{
/** @var MyEntityRepository */
protected $myEntityRepository;
// this injection of MyEntityRepository creates the problem
// with the two instances of the EntityManager
// unless the MyEntityListener is tagged as lazy
public function __construct(MyEntityRepository $myEntityRepository)
{
$this->myEntityRepository = $myEntityRepository;
}
// ...
}