I am trying to blend ODM (MongoDB) and ORM in my Symfony 2.6 with a reference to the Documentation "Blending ORM and MongoDB ODM"
I have two entities, User
and Category
. Also I have one Document Product
.
It's clear when blending ODM and ORM, it can be solved easily with OneToMany or ManyToOne case - on one side we define ReferenceOne link + both field
specifing identifier="fieldId"
and fieldId
itself, on another side we define ReferenceMany).
My challenge is getting $product->categories
populated with relation ManyToMany. So far, $product->user
is getting retrieved normally, when $product->userId
is filled. But I can't achieve the same with $product->categories
.
Can you help me to find a solution?
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
{
/**
* @var ArrayCollection $products
*
* @Gedmo\ReferenceMany(type="document", class="Document\Product", mappedBy="user")
*/
protected $products;
}
/**
* @Gedmo\Tree(type="nested")
* @ORM\Entity
* @ORM\Table(name="categories")
*/
class Category
{
/**
* @var ArrayCollection $products
*
* @Gedmo\ReferenceMany(type="document", class="Document\Product", mappedBy="products")
*/
protected $products;
}
and then I have a Document
/**
* @MongoDB\Document
* @MongoDB\HasLifecycleCallbacks
*/
class Product
{
/**
* @Gedmo\ReferenceOne(type="entity", class="Entity\User", inversedBy="products", identifier="userId")
*/
protected $user;
/**
* @MongoDB\Field(name="user_id", type="int")
*/
protected $userId;
/**
* @Gedmo\ReferenceMany(type="entity", class="Entity\Category", mappedBy="products")
*/
protected $categories = array();
/**
* @MongoDB\Collection
*/
protected $categoryIds = array();
public function getUser()
{
return $this->user;
}
public function getCategories()
{
return $this->categories;
}
}
P.S> listeners gedmo.listener.reference
and utils.listener.reference
do exist.
There is actual documentation for that use case provided by doctrine:
Blending the ORM and MongoDB ODM
It's basically a manual implementation of doctrine's reference model. In short: You store an id ( or a list of ids) in a property that is mapped and persisted via doctrine.
Then during the load process (either via event listener or method annotations) you fetch the respective documents and store them in separate property. Then during the flush process (either via event listener or method annotations) you get the (possibly changed) objects's id(s) and put them back in your first property.
We have been using a slightly altered version of this approach in our core product for years now and it works fine, without any hiccups and very transparently.
For the more curious: It's also possible ( and harder but more convenient in the long run ) to built a custom doctrine type for that.