Reputation: 2331
I need to store an array of Document (doctrine ODM) into an Entity stored in relational database (Doctrine ORM). I choose to store the identifiers of my Documents as a string containing a comma separated list of Document identifiers.
I found that I can add a PostLoad event on the ORM side to lazy load my documents: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/1.2.x/cookbook/blending-orm-and-mongodb-odm.html
But the DocumentManager::getReference method only allows to load a single object. Isn't it any way to build something similar to fetch a list of objects ?
Upvotes: 1
Views: 293
Reputation: 657
I would do it by creating a new collection extending Doctrine\Common\Collections\AbstractLazyCollection
;
Example code (not tested):
<?php
use Doctrine\Common\Collections\AbstractLazyCollection;
use Doctrine\ODM\MongoDB\DocumentManager;
class LazyArrayRelationshipCollection extends AbstractLazyCollection
{
private $dm;
private $className;
private $ids;
public function __construct(DocumentManager $dm, $className, array $ids)
{
$this->dm = $dm;
$this->className = $className;
$this->ids = $ids;
}
protected function doInitialize()
{
$class = $this->dm->getClassMetadata($this->className);
$this->collection = $this->dm->getRepository($this->className)
->findBy([$class->identifier[0] => $this->ids]);
}
}
And subscriber:
<?php
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\Event\LifecycleEventArgs;
class MyEventSubscriber
{
public function __construct(DocumentManager $dm)
{
$this->dm = $dm;
}
public function postLoad(LifecycleEventArgs $eventArgs)
{
$order = $eventArgs->getEntity();
$em = $eventArgs->getEntityManager();
$productReflProp = $em->getClassMetadata(Entities\Order::class)
->reflClass->getProperty('products');
$productReflProp->setAccessible(true);
$productReflProp->setValue(
$order, new LazyArrayRelationshipCollection($this->dm, Documents\Product::class, $order->getProductIds())
);
}
}
Or you could go a more "dirty" way and loop over you ids, call DocumentManager::getReference
on each of them, and return an ArrayCollection
of those, it would probably work to.
Upvotes: 0