Reference ORM (Entity) from ODM (Document, MongoDB) with ManyToMany relationship

1.7k views Asked by At

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.

1

There are 1 answers

2
Jan On

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.