Php Symfony2/Doctrine2:在侦听器中管理多实体管理器的问题
我正在按照配方Php Symfony2/Doctrine2:在侦听器中管理多实体管理器的问题,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,我正在按照配方http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-订阅服务器,当我到达事件订阅服务器时,我无法插入正确的实体管理器,名为$this->dm的一个已在构造函数中初始化 据我所知,正在加载的实体使用的实体管理器可以通过$em=$eventArgs->getEntityManager()检索然后我
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-订阅服务器
,当我到达事件订阅服务器时,我无法插入正确的实体管理器
,名为$this->dm
的一个已在构造函数中初始化
据我所知,正在加载的实体使用的实体管理器可以通过$em=$eventArgs->getEntityManager()检索
然后我需要另一个,我以以下方式注入它:
services:
postload.listener:
class: myVendor\myFooBarBundle\Listener\myEntityListener
tags:
- { name: doctrine.event_listener, event: postLoad }
arguments:
- "@doctrine.orm.foobar_entity_manager"
这是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 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".
在第28行“SonataAdminBundle:CRUD:base\u list.html.twig”中的模板呈现过程中引发异常(“类myVendor\myFooBarBundle\View\myFooBarEntity不是有效的实体或映射的超类”。
上述错误是由$fooBarEntity=$eventArgs->getEntityManager('foobar')->getRepository('myVendor\myFooBarBundle\View\myFooBarEntity')->findOneBy(数组('id'=>$myEntity->getFooBarEntityId())引起的代码>因为当我放置echo“hello”时;模具();在该行之前不会抛出错误,但在该行之后放置时会抛出错误,并且不会显示hello
。这个错误让我觉得,尽管我通过$eventArgs->getEntityManager('foobar')
显式地获得了foobar
连接,但它仍然为我提供了默认的连接/实体管理器
为了仔细检查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();
if(strpos($className,'myFooBarEntity'))
{
回显“类:”.$className.\n\n;
foreach($this->\驱动程序作为$namespace=>$driver)
{
回显“名称空间:”.$namespace.\n;
$bool=strpos($className,$namespace);
var_dump(布尔美元);
回显“\n\n”;
}
}
模具();
DriverCain代码给了我以下信息,这就是为什么我认为从来没有使用过“foobar”连接,或者symfony有某种错误解释orm.yml
文件,该文件定义了实体管理器以及要使用的名称空间
类别:myVendor\myFooBarBundle\View\myFooBarEntity
命名空间:myVendor\myFooBarBundle\Entity
布尔(假)
如果我在myVendor\myFooBarBundle\View\myFooBarEntity
中查找@ORM\entity
实体定义,以及@ORM\OneToMany(targetEntity=…)
与另一个实体的关系
我希望有人能帮上忙,因为这快把我逼疯了。非常感谢 我想我看到了你的问题:
您试图处理的实体不由您正在使用的实体管理器管理
原因是在第一个示例中,您只处理服务doctrine.orm.foobar\u entity\u manager
,它不知道myVendor\myFooBarBundle\entity
entites
在第二个示例中,您尝试使用:$eventArgs->getEntityManager('foobar')
访问不同的EntityManager,但这不起作用。EventArgs只附加到一个entityManager,并且没有参数(如“foobar”)来访问另一个entityManager
因此,我在这里看到的最佳解决方案是,像你的第一个想法那样行事,但同时注入两种元素:
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"
如果您有循环依赖项检测,请尝试注入原则
服务,它是Symfony\Bridge\doctor\manager注册表
的一个实例。我找到了一个解决方案:
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');
....
}
}
}
您现在可以使用多个实体管理器。最后一个示例在更改后开始适用于我
使用Symfony\Bundle\DoctrineBundle\Registry;使用条令\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');
....
}
}
}
名称空间myVendor\myFooBarBundle\Listener\myEntityListener;
使用条令\Bundle\DoctrineBundle\Registry
类MyFooberEntityListener
{
私人$reg;
公共函数构造(注册表$reg)
{
//不要放置entitymanager,否则在创建过程中会出现循环
$this->reg=$reg;
}
公共函数加载后(LifecycleEventArgs$eventArgs)
{
$myEntity=$eventArgs->getEntity();
if($myEntity instanceof\myVendor\myFooBarBundle\Entity\myEntity)
{
$em=$this->reg->getEntityManager('not_default');
$userPointdbManager=$em->getRepository('FullerUserBundle:UserPointdb');
....
}
}
}
不要将Registry设置为参数,但要设置RegistryInterface(使用Symfony\Bridge\Doctrine\RegistryInterface)非常感谢您的回答。我已经试过了,注入两个实体管理器,注入服务容器,然后得到条令服务,注入条令服务,然后得到两个实体管理器,但我总是得到循环引用错误。你知道我还能做什么吗?高级感谢:)最后,我查看了l3pp4rd DoctrineBehaviours
,并根据他的结构创建了一个更高级的侦听器,从doctrine
服务中获取这两个连接没有问题。那么这些答案中的任何一个是否可以标记为已接受,或者至少可以发布您的解决方案@user846226?提前谢谢。
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');
....
}
}
}
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');
....
}
}
}