为什么我的Doctrine自定义repositoty认为,我的实体是分离的?

时间:2017-09-29 09:02:36

标签: symfony doctrine-orm

我的自定义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
}

1 个答案:

答案 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;
    }
    // ...
}
相关问题