Doctrine OneToOne/ManyToOne association with Table inheritance

There’s this “general performance consideration” with Single Table Inheritance (STI) and Class Table Inheritance (CTI) in Doctrine:

If the target-entity of a many-to-one or one-to-one association is an STI/CTI entity, it is preferable for performance reasons that it be a leaf entity in the inheritance hierarchy, (ie. have no subclasses). Otherwise Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.

The problem is illustrated very clearly by @timdev in a SO answer:

abstract class Pet { ... }
class Cat extends Pet { ... } 
class Dog extends Pet { ... }

class Collar {
   /** @Column(length="16") */
   protected $color;

   /** ManyToOne(targetEntity="Pet")*/
   protected $owner;

Now, if you wanted to iterate over all the blue collars, Doctrine runs into some trouble. It doesn’t know what class $owner is going to be, so it can’t use a Proxy. Instead, it’s forced to eagerly load $owner to find out whether it’s a Cat or a Dog.

OK, so my question is: what if I do need to iterate over the blue collars in my app (for instance because I want them listed in a web page).

What is the recommended solution to work around the performance problem? Should I switch to a ManyToMany association, even if it doesn’t make much sense, or rethink my data modeling?

Source: oop

Leave a Reply