我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
的实体管理器:
服务业: postload.listener: class: myVendor''myFooBarBundle''Listener''myEntityListener 标签: - { 名称:doctrine.event_listener,事件:后加载 } 参数: - "@doctrine.orm.foobar_entity_manager">
这些是我的实体经理:
orm.yml 或: entity_managers: 违约: 连接:默认 映射: myVendormyFooBarBundle: 前缀:"myVendor''myFooBarBundle''Entity" 类型:注释 is_bundle:真 目录:"实体" 福巴: 连接: 福巴 映射: myVendormyFooBarBundle: 前缀:"myVendor''myFooBarBundle''View" 类型:注释 is_bundle:真 目录:"查看">
使用上述策略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( Lifecycle EventArgs $eventArgs ( { $myEntity = $eventArgs->getEntity((; if( $myEntity instanceof ''myVendor''myFooBarBundle''Entity''myEntity ( { $em = $eventArgs->getEntityManager((; $fooBarReflProp = $em->getClassMetadata( 'myVendor''myFooBarBundle''Entity''Entity''myEntity' (->reflClass->getProperty( 'FooBarEntity' (; $fooBarReflProp->setAccess( true (; $fooBarEntity = $this->em->getRepository( 'myVendor''myFooBarBundle''View''myFooBarEntity' (->findOneBy( array( 'id' => $myEntity->getFooBarEntityId(( ( (; $fooBarReflProp->setValue( $myEntity, $fooBarEntity (; } } }
另外为了避免我尝试not
注入foobar entity manager
并通过LifecycleEventArgs $eventArgs
circular reference error
:
class myFooBarEntityListener { public function postLoad( Lifecycle EventArgs $eventArgs ( { $myEntity = $eventArgs->getEntity((; if( $myEntity instanceof ''myVendor''myFooBarBundle''Entity''myEntity ( { $em = $eventArgs->getEntityManager((; $fooBarReflProp = $em->getClassMetadata( 'myVendor''myFooBarBundle''Entity''Entity''myEntity' (->reflClass->getProperty( 'FooBarEntity' (; $fooBarReflProp->setAccess( true (; 请注意,在这里我应该如何通过$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() ) );
引起的,因为当我放置回显'hello';d ie((时,错误不会抛出,但是当放置在该行之后时,错误被抛出并且hello
没有显示。这个错误让我觉得虽然我明确地通过$eventArgs->getEntityManager('foobar')
获得了foobar
连接,但它仍然给了我default
connection/entity manager
。
为了仔细检查myVendor'myFooBarBundle'View'myFooBarEntity
语法,我转到octrine'ORM'Mapping'Driver'DriverChain
并放置了以下代码:
if( strpos( $className, 'myFooBarEntity' ( ( { 回声"类:".$className。''"; foreach ($this->_drivers as $namespace => $driver( { 回显"命名空间:".$namespace"。'"; $bool = strpos($className, $namespace(; var_dump($bool(; 回显"''"; } } 死((;
该DriverChain代码给了我以下内容,这就是为什么我认为从未使用过"foobar"连接,或者symfony在定义实体管理器和要使用的命名空间orm.yml
文件中具有某种错误解释。
class: myVendor''myFooBarBundle''View''myFooBarEntity
命名空间:myVendor''myFooBarBundle''Entity布尔值(假(
如果我在myVendor'myFooBarBundle'View'myFooBarEntity
里面查看entity
词,我只会找到实体定义@ORM'Entity
,也@ORM'OneToMany( targetEntity=.....)
与另一个实体的关系。
我希望有人能帮忙,因为这让我发疯。多谢!!
我找到了一个解决方案:
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');
....
}
}
}
您现在可以使用多个实体管理器。
我想我看到了你的问题:
您正在尝试处理不由您正在使用的实体管理器管理的对象。
原因是在您的第一个示例中,您在服务doctrine.orm.foobar_entity_manager
上工作,不知道myVendor'myFooBarBundle'Entity
。
在第二个中,您尝试使用以下方法访问不同的实体管理器: $eventArgs->getEntityManager('foobar')
但这不起作用。EventArgs只附加到一个实体管理器,并且没有参数(如"foobar"(可以访问另一个实体管理器。
所以我在这里看到的最佳解决方案是像你的第一个想法一样行事,但注入两个实体经理:
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
的实例。
不要将 Registry 设置为参数,而是将 RegistryInterface 设置为参数(使用 Symfony''Bridge''Doctrine''RegistryInterface(
更改后,最后一个示例开始为我工作使用 Symfony''Bundle''DoctrineBundle''Registry;使用 Doctrine''Bundle''DoctrineBundle''Registry;。
所以它应该是:
namespace myVendor''myFooBarBundle''Listener''myEntityListener;使用原则''捆绑包''原则捆绑包''注册表class myFooBarEntityListener{ 私人$reg; 公共功能__construct(注册表$reg( { 不要放置实体管理器,否则在创建过程中会出现循环 $this->reg = $reg; } public function postLoad( Lifecycle EventArgs $eventArgs ( { $myEntity = $eventArgs->getEntity((; if( $myEntity instanceof ''myVendor''myFooBarBundle''Entity''myEntity ( { $em = $this->reg->getEntityManager('not_default'(; $userPointdbManager = $em->getRepository('FullerUserBundle:UserPointdb'(; .... } }}