问题描述
我正在追踪该食谱 http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm .html#event-subscriber
,当我到达事件订阅者时,我无法注入适当的实体管理器
,名为 $ this-> dm
在构造函数中初始化。
i'm following that recipe http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-subscriber
and when i get to the event subscriber i'm not able to inject the proper entity manager
, the one named $this->dm
initialized in the constructor.
据了解,正在加载的实体使用的实体管理器可以通过 $ em = $ eventArgs-> getEntityManager );
然后我需要另外一个我注入
,方式如下:
As i understand, the entity manager used by the entity which is being loaded can be retrieved through $em = $eventArgs->getEntityManager();
then i need another one which i inject
in the following manner:
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"
当使用上述策略注入
foobar实体管理器
时,我会收到以下错误:
When injecting
the foobar entity manager
using the above strategy i get the following error:
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:
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 );
}
}
}
还要避免循环引用错误
我尝试不
注入 foobar实体管理器
,并通过 LifecycleEventArgs $ eventArgs
:
Also to avoid the circular reference error
i've tried not
to inject the foobar entity manager
and get it through 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 );
}
}
}
最后一个实现通过我以下错误:
That last implementation throughs me the following error:
在渲染模板期间抛出异常(Class myVendor\myFooBarBundle\View\myFooBarEntity不是有效的实体或映射的超级类。)在第28行的SonataAdminBundle:CRUD:base_list.html.twig中。
上述错误是由通过 $ fooBarEntity = $ eventArgs-> getEntityManager('foobar') - > getRepository('myVendor\myFooBarBundle\View\myFooBarEntity') - > findOneBy(array('id'=因为我放置echo'hello'; die();在该行之前,错误不会被抛出,但是当放置在行之后,错误被抛出,并且
hello
未显示。这个错误让我觉得,虽然我明确地通过 $ eventArgs-> getEntityManager('foobar')$ c获取
foobar
$ c>它仍然给我默认值
连接/实体管理器
。
The above error is caused by $fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) );
because when i place echo 'hello';die(); just before that line the error is not thrown but when placed just after the line the error is thrown and hello
is not shown. The error makes me think that although i'm explicitly getting the foobar
connection through $eventArgs->getEntityManager('foobar')
it is still giving me the default
connection/entity manager
.
为了双重检查 myVendor\myFooBarBundle\View\myFooBarEntity
语法我去了 octrine\ORM\ Mapping\Driver\DriverChain
并放置以下代码:
In order to double check myVendor\myFooBarBundle\View\myFooBarEntity
syntax i went to octrine\ORM\Mapping\Driver\DriverChain
and placed the following code:
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
文件,定义实体管理器加上使用的命名空间。
That DriverChain code gives me the following, that's why i think 'foobar' connection is never used or symfony has some kind of bug interpreting orm.yml
file which defines the entity managers plus namespaces to use.
class:myVendor\ myFooBarBundle\View\myFooBarEntity
class: myVendor\myFooBarBundle\View\myFooBarEntity
命名空间:myVendor\myFooBarBundle\Entity
bool(false)
namespace: myVendor\myFooBarBundle\Entitybool(false)
如果我在 myVendor\myFooBarBundle\View\myFooBarEntity $ c $中看到
实体
c>我只是为实体定义找到 @ ORM\Entity
,而且 @ ORM\OneToMany(targetEntity = .....)
与另一个实体的关系。
If i look foor the entity
word inside myVendor\myFooBarBundle\View\myFooBarEntity
i just find @ORM\Entity
for the entity definition and also @ORM\OneToMany( targetEntity=.....)
for the relation with another entity.
我希望有人可以帮助,因为它让我疯狂。非常感谢!
I hope someone can help, as it's driving me crazy. Thanks a lot!!
推荐答案
我找到了一个解决方案:
I found a solution:
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');
....
}
}
}
您现在可以使用多个实体管理员。
You can use several entity managers now.
这篇关于Symfony2 / Doctrine2:在监听器中管理多个实体管理器的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!