我正在关注那个食谱http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-subscriber
,当我到达事件订阅者时,我无法注入正确的entity manager
,在构造函数中初始化了$this->dm
。
据我了解,正在加载的实体使用的实体管理器可以通过$em = $eventArgs->getEntityManager();
检索,然后我需要另一个以inject
方式执行的实体管理器:
services: postload.listener: class: myVendor\myFooBarBundle\Listener\myEntityListener tags: - { name: doctrine.event_listener, event: postLoad } arguments: - "@doctrine.orm.foobar_entity_manager"
这些是我的实体经理:
//orm.yml orm: entity_managers: default: connection: default mappings: myVendormyFooBarBundle: prefix: "myVendor\myFooBarBundle\Entity" type: annotation is_bundle: true dir: "Entity" foobar: connection: foobar mappings: myVendormyFooBarBundle: prefix: "myVendor\myFooBarBundle\View" type: annotation is_bundle: true dir: "View"
使用上述策略injecting
时foobar entity manager
我收到以下错误:
Circular reference detected for service "postload.listener", path: "routing.loader -> routing.db.loader -> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> postload.listener -> doctrine.orm.fooba_entity_manager -> doctrine.dbal.foobar_connection".
那是myVendor\myFooBarBundle\Listener\myEntityListener
课程:
class myFooBarEntityListener { public function __construct( \Doctrine\ORM\EntityManager $em ) { $this->em = $em; } public function postLoad( LifecycleEventArgs $eventArgs ) { $myEntity = $eventArgs->getEntity(); if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity ) { $em = $eventArgs->getEntityManager(); $fooBarReflProp = $em->getClassMetadata( 'myVendor\myFooBarBundle\Entity\myEntity' )->reflClass->getProperty( 'FooBarEntity' ); $fooBarReflProp->setAccessible( true ); $fooBarEntity = $this->em->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) ); $fooBarReflProp->setValue( $myEntity, $fooBarEntity ); } } }
另外要避免circular reference error
我尝试not
注入foobar entity manager
并通过LifecycleEventArgs $eventArgs
:
class myFooBarEntityListener { public function postLoad( LifecycleEventArgs $eventArgs ) { $myEntity = $eventArgs->getEntity(); if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity ) { $em = $eventArgs->getEntityManager(); $fooBarReflProp = $em->getClassMetadata( 'myVendor\myFooBarBundle\Entity\myEntity' )->reflClass->getProperty( 'FooBarEntity' ); $fooBarReflProp->setAccessible( true ); //NOTICE HOW HERE I SHOULD GET THE PROPER ENTITY MANAGER THROUGH $eventArgs $fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) ); $fooBarReflProp->setValue( $myEntity, $fooBarEntity ); } } }
最后一次实现通过以下错误:
An exception has been thrown during the rendering of a template ("Class myVendor\myFooBarBundle\View\myFooBarEntity is not a valid entity or mapped super class.") in "SonataAdminBundle:CRUD:base_list.html.twig" at line 28.
上述错误是由$fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) );
引起的,因为当我发出echo'hello'; die();就在该行之前,不会抛出错误,但是当在行之后放置时会抛出错误并且不显示hello
。这个错误让我觉得虽然我明确地通过foobar
获得了$eventArgs->getEntityManager('foobar')
连接,但它仍然给我default
connection/entity manager
。
为了仔细检查myVendor\myFooBarBundle\View\myFooBarEntity
语法,我转到octrine\ORM\Mapping\Driver\DriverChain
并输入以下代码:
if( strpos( $className, 'myFooBarEntity' ) ) { echo 'Class: '.$className."\n\n"; foreach ($this->_drivers as $namespace => $driver) { echo 'namespace: '.$namespace."\n"; $bool = strpos($className, $namespace); var_dump($bool); echo "\n\n"; } } die();
那个DriverChain代码给了我以下内容,这就是为什么我认为'foobar'连接从未被使用过,或者symfony有某种错误解释orm.yml
文件,它定义了实体管理器和名称空间来使用。
class:myVendor \ myFooBarBundle \ View \ myFooBarEntity
命名空间:myVendor \ myFooBarBundle \ Entity 布尔(假)
如果我看一下entity
内的myVendor\myFooBarBundle\View\myFooBarEntity
字,我只找到@ORM\Entity
作为实体定义,还@ORM\OneToMany( targetEntity=.....)
表示与另一个实体的关系。
我希望有人可以提供帮助,因为它让我发疯。非常感谢!!
答案 0 :(得分:2)
我找到了解决方案:
services:
postload.listener:
class: myVendor\myFooBarBundle\Listener\myEntityListener
tags:
- { name: doctrine.event_listener, event: postLoad }
arguments:
- @doctrine
我的听众:
namespace myVendor\myFooBarBundle\Listener\myEntityListener;
use Symfony\Bundle\DoctrineBundle\Registry;
class myFooBarEntityListener
{
private $reg;
public function __construct(Registry $reg)
{
//dont't put your entitymanager otherwise a loop appear during creation
$this->reg = $reg;
}
public function postLoad( LifecycleEventArgs $eventArgs )
{
$myEntity = $eventArgs->getEntity();
if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity )
{
$em = $this->reg->getEntityManager('not_default');
$userPointdbManager = $em->getRepository('FullerUserBundle:UserPointdb');
....
}
}
}
您现在可以使用多个实体经理。
答案 1 :(得分:1)
我想我看到了你的问题:
您正在尝试使用不受您正在使用的entityManager管理的Entites。
原因是,在您的第一个示例中,您正在处理服务doctrine.orm.foobar_entity_manager
,但不了解myVendor\myFooBarBundle\Entity
entites。
在第二个中,您尝试使用:$eventArgs->getEntityManager('foobar')
访问不同的entityManagers,但这不起作用。 EventArgs只附加到一个entityManager,并且没有参数(比如'foobar')来访问另一个。
所以我在这里看到的最好的解决方案就是像你的第一个想法一样,但注入两个entityMangers:
services:
postload.listener:
class: myVendor\myFooBarBundle\Listener\myEntityListener
tags:
- { name: doctrine.event_listener, event: postLoad }
arguments:
- "@doctrine.orm.default_entity_manager"
- "@doctrine.orm.foobar_entity_manager"
如果您有循环依赖关系检测,请尝试注入doctrine
服务,该服务是Symfony\Bridge\Doctrine\ManagerRegistry
的实例。
答案 2 :(得分:1)
不要将Registry设置为参数,而是设置RegistryInterface(使用Symfony \ Bridge \ Doctrine \ RegistryInterface)
答案 3 :(得分:0)
最后一个例子在改变后开始为我工作 使用Symfony \ Bundle \ DoctrineBundle \ Registry;使用Doctrine \ Bundle \ DoctrineBundle \ Registry;。
所以它应该是:
namespace myVendor\myFooBarBundle\Listener\myEntityListener; use Doctrine\Bundle\DoctrineBundle\Registry class myFooBarEntityListener { private $reg; public function __construct(Registry $reg) { //dont't put your entitymanager otherwise a loop appear during creation $this->reg = $reg; } public function postLoad( LifecycleEventArgs $eventArgs ) { $myEntity = $eventArgs->getEntity(); if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity ) { $em = $this->reg->getEntityManager('not_default'); $userPointdbManager = $em->getRepository('FullerUserBundle:UserPointdb'); .... } } }