symfony - 为什么我的 Doctrine 自定义存储库认为我的实体是分离的?

标签 symfony doctrine-orm

我的自定义 Doctrine2 存储库有一个奇怪的问题。

我有一个 DELETE Controller ,它基本上如下所示:

public function deleteAction(MyEntity $myEntity, MyEntityRepository $myEntityRepository)
{
    $myEntityRepository->remove($myEntity);
    $myEntityRepository->flushEntityManager();

    return new JsonResponse(['message' => 'Bye bye!']);
}

存储库的删除方法如下所示:

public function remove(MyEntity $entity): MyEntityRepository
{
    $this->getEntityManager()->remove($entity);
    return $this;
}

这以前有效,但现在,我遇到了异常:

无法删除分离的实体 AppBundle\Entity\MyEntity@000000003b458c32000000007fd2994a

我真的不知道,为什么存储库内的EntityManager认为实体是分离的。当我将 EntityManager 直接注入(inject)到我的 Controller 时,一切正常:

public function deleteAction(MyEntity $myEntity, EntityManagerInterface $em)
{
    $em->remove($myEntity);
    $em->flush();

    return new JsonResponse(['message' => 'Bye bye!']);
}

对此有什么想法吗?为什么我从 Doctrine\ORM\EntityRepository->getEntityManager() 获得的 EntityManager 与注入(inject)到我的 Controller 中的 EntityManager 不同?

附注我的其他删除操作没有这个问题,它们都使用相同的自定义存储库。这让我发疯。

编辑:在存储库中转储 $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
}

在 Controller 内转储$em时出现

DoctrineORMEntityManager_00000000644c03b80000000000dac8cc6811571fd60520ff7ea135d840b51abe {#410 ▼
-valueHolder59cfe1676bb7b138763071: EntityManager {#664 …11}
-initializer59cfe1676bb84613288121: null
}

最佳答案

我创建了一个新的空 Symfony 项目来逐步重现该问题。当我实现实体监听器时,我遇到了同样的错误,该监听器有一个辅助类作为依赖项,该类本身也有 MyEntityRepository 作为依赖项。删除此依赖项可以解决分离实体的问题。

后来进行了一些进一步的调查,我意识到,注入(inject)的 EntityManager 实例有时是新实例。要注入(inject)主实例(并顺便消除循环引用错误),您可以将实体监听器服务标记为惰性:

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 }

这个懒惰的东西解决了我的问题!

但我仍然不明白,为什么当另一个服务注入(inject)此存储库时,我会将另一个 EntityManager 实例注入(inject)到我的存储库中。

作为记录,MyEntityRepository 配置:

AppBundle\Entity\Repository\MyEntityRepository:
    autowire: false
    autoconfigure: true
    public: false
    factory: ['@doctrine.orm.default_entity_manager', getRepository]
    arguments:
        - AppBundle\Entity\MyEntity

监听器服务:

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;
    }
    // ...
}

关于symfony - 为什么我的 Doctrine 自定义存储库认为我的实体是分离的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46485397/

相关文章:

php - 学说一对一关系映射

php - 如何在 Symfony2 中停止对约束失败的验证

php - '调用非对象的成员函数 get()'?

symfony - 为硬删除记录禁用软删除过滤器不起作用

php - JMS 序列化器在 Mysql BLOB 反序列化上返回资源 id #xxx

php - 学说 2 @joincolumns

php - 内存管理 Symfony 表单和 Doctrine

symfony - 如何用phpunit模拟依赖注入(inject)?

symfony - Symfony2 Controller 中的构造函数

php - FOSUserBundle 未在 DoctrineFixtures 中设置盐