Я следую этому рецепту 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
, который определяет менеджеры сущностей плюс пространства имен для использования.
класс: myVendor \ myFooBarBundle \ View \ myFooBarEntity
пространство имен: myVendor \ myFooBarBundle \ Entity
BOOL (ложь)
Если я посмотрю на слово entity
внутри myVendor\myFooBarBundle\View\myFooBarEntity
, я просто найду @ORM\Entity
для определения сущности, а также @ORM\OneToMany( targetEntity=.....)
для связи с другой сущностью.
Я надеюсь, что кто-то может помочь, потому что это сводит меня с ума. Большое спасибо !!