问题:如何使用与doctrine一起使用继承映射的关联对象加载对象?
例如使用这些对象: (忽略拼写错误,我从我的真实示例代码中重命名了一些东西)
/**
* @ORM\Table(name="int_entity")
* @ORM\Entity
* })
*/
class IntEntity extends BaseEntity
{
/**
* @ORM\Column(name="int_value", type="integer", nullable=true)
**/
public $intValue;
}
/**
* @ORM\Table(name="float_entity")
* @ORM\Entity
* })
*/
class floatEntity extends FakeBaseMixedEntity
{
/**
* @ORM\Column(name="float_value", type="float", nullable=true)
**/
public $floatValue;
}
/** @ORM\MappedSuperclass */
class BaseEntity
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
*/
private $id;
//could be other variables I guess but I didn't need any. The point of the
//base class in my case is more of an interface I guess...
}
/**
* @ORM\Table(name="Entity_Containing_Inherited_Entity")
* @ORM\Entity
* })
*/
class EntityContainingInheritedEntity
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* @ORM\Column(name="string_value", type="string")
*/
public $stringValue;
/**
* @ORM\OneToOne(targetEntity="BaseEntity", cascade={"persist"})
* @ORM\JoinColumn(name="id", referencedColumnName="id")
**/
public $mixedEntity;
}
加载不起作用
$em = $this->getDoctrine()->getManager();
$loadedValue = $em->getRepository('BundleName:EntityContainingInheritedEntity')->findAll();
然而保存
public function indexAction(Request $request)
{
$floatE = new floatEntity();
$floatE->floatValue = 1.01;
$floatE->setId(rand());
$floatEContainer = new EntityContainingInheritedEntity();
$floatEContainer->stringValue = 'hello';
$floatEContainer->mixedEntity = $floatE;
$intE = new intEntity();
$intE->intValue = 100;
$intE->setId(rand());
$intEContainer = new EntityContainingInheritedEntity();
$intEContainer->stringValue = 'hello';
$intEContainer->mixedEntity = $intE;
$em = $this->getDoctrine()->getManager();
$em->persist($floatEContainer);
$em->persist($intEContainer );
$em->flush();
}
加载时说代理不存在。所以我搜索了一下,首先,当有像这样的继承映射时,学说甚至不应该尝试创建代理(至少我是如何解释文档http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#performance-impact
我已经清除了我的缓存没有改变 我试图在注释中添加急切的加载,没有任何改变 我也有点从我的搜索得到我要使用DQL而不是findAll()下面有相同的代理缓存错误消息
$query = $em->createQuery("SELECT u FROM Path\To\Entity\EntityContainingInheritedEntity u");
$users = $query->getResult();
提到的错误消息:ContextErrorException:警告:require(/path/app/cache/dev/doctrine/orm/Proxies/__CG__BundleNameEntityBaseEntity.php):无法打开流:/ path / vendor / doctrine中没有此类文件或目录/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php
顺便说一句,这并没有解决我的问题:Doctrine 2 Inheritance Mapping with Association
答案 0 :(得分:0)
根据Alberto Fernandez的评论,我不应该做我做的事情。这让我很困惑,因为它保存得当。尽管如此,如果他没有任何关于如何做到这一点的例子,我继续搜索。我发现我的问题的最佳解决方案是不映射关联的实体。相反,我迷上了事件监听器,即 http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html和 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html这使我能够坚持并按照我想要的方式加载相关实体。我将使用我的解决方案再次使用上面的示例。
EntityContainingInheritedEntity已更改为
/**
* @ORM\Table(name="Entity_Containing_Inherited_Entity")
* @ORM\Entity
* })
*/
class EntityContainingInheritedEntity
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* @ORM\Column(name="string_value", type="string")
*/
public $stringValue;
public $mixedEntity;
public $mixedEntityType;
public function load($em)
{
$this->mixedEntity= $em->getRepository("BundleName:{$this->mixedEntityType}")->find($this->id);
}
public function save($em)
{
$this->mixedEntity->SetId($this->id);
$em->persist($this->mixedEntity);
$em->flush();
}
public function delete($em)
{
$em->remove($this->mixedEntity);
$em->flush();
}
}
我将此添加到我的config.yml
services:
my.listener:
class: Path\To\EventListeners\RecordAssociationManager
tags:
- { name: doctrine.event_listener, event: postPersist }
my.listener2:
class: Path\To\EventListeners\RecordAssociationManager
tags:
- { name: doctrine.event_listener, event: preRemove }
my.listener3:
class: Path\To\EventListeners\RecordAssociationManager
tags:
- { name: doctrine.event_listener, event: postLoad }
然后制作了事件监听器类
namespace Path\To\EventListeners;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Path\To\Entity\EntityContainingInheritedEntity;
class RecordAssociationManager
{
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if ($entity instanceof EntityContainingInheritedEntity)
{
$entity->delete($entityManager);
}
}
public function postPersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if ($entity instanceof EntityContainingInheritedEntity)
{
$entity->save($entityManager);
}
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if ($entity instanceof EntityContainingInheritedEntity)
{
$entity->load($entityManager);
}
}
}