Search code examples
symfonydoctrine-ormdoctrineassociationsmodel-associations

How to limit OneToMany/ManyToOne associations depth/loop in Doctrine2?


I've 3 doctrine entities. One is User, second is Product and third is ProductUsers.

So, User have OneToMany association with ProductUsers and the same Product have OneToMany association with ProductUsers. ProductUsers has ManyToOne association with both User and Product. Like so:

class Product
{
    /**
     * @var ProductUsers
     *
     * @ORM\OneToMany(targetEntity="ProductUsers", mappedBy="product")
     */
    private $productUsers;
}

class ProductUsers
{
    /**
     * @var Product
     *
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="productUsers")
     * @ORM\JoinColumn(name="product_ID", referencedColumnName="ID")
     */
    private $product;

    /**
     * @var User
     *
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="User", inversedBy="productUsers")
     * @ORM\JoinColumn(name="user_ID", referencedColumnName="ID")
     */
    private $user;

    // extra fields ...
}

class User
{
    /**
     * @var ProductUsers
     *
     * @ORM\OneToMany(targetEntity="ProductUsers", mappedBy="user")
     */
    private $productUsers;
}

A user can use multiple products and a product can have multiple users. ProductUsers has some extra info about the relation other than just the relation.

The problem is when I fetch one User object it comes with associated ProductUsers and it's associated Product. Not only that but the Product also comes with all it's associated ProductUsers and it's respective User objects which is quite an overhead.

This question closely relates to my problem.

I'm looking to limit that at doctrine level just like what JMSSerializerBundle MaxDepth does. Is there a way to limit such overhead in doctrine?


Solution

  • I faced this issue long time back. I tried lazy loading. Which didn't work as expected and that was not a proper solution to my issue. So I did some R&D and came up with a solution that I don't need a bidirectional relationship from Product to ProductUsers.

    I can manage same relationship with unidirectional handling only from ProductUsers side. You will need One-To-Many Association when you need a cascade-persist or similar feature. I wrote a small blog regarding this as well.

    So, for your solution, just have Many-To-One association from ProductUsers with both Product and User entity. You will not need any change in your database association.

    And when you need Products associated for a single user, you can always save a Querybuilder in Repository to use when you need associated data.

    It will save a lot of performance. Hope it helps!