Search code examples
sqloopinheritancedoctrine-ormentity

What is a leaf entity in the inheritance hierarchy and what are examples of?


The following was provided by Inheritance Mapping - Doctrine and was only modified to pertain to both STI and CTI.

There is a general performance consideration with Single or Class Table Inheritance (STI or CTI): If the target-entity of a many-to-one or one-to-one association is a STI or 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.

In addition to the Doctrine docs, What is a leaf entity? provides a similar description, however, I still don't have a clear enough understanding, and would like to see examples.

Let's say I have entities V8Engine, V6Engine, and Straight4Engine which all extend AbstractEngine, and another entity Automobile where many automobiles have one engine (sorry for my fictional example and change if you think necessary). Please describe what leaf entities are and provide an example of both where the target-entity is and is not a leaf entity.


Solution

  • I think you're asking two questions:

    1. What are leaf entities?
    2. What if I use an entity with (Single or Class) Table Inheritance as a target entity?

    1. What are leaf entities?

    Let say you've got these classes:

    abstract class AbstractEngine {}
    final class V6Engine extends AbstractEngine {}
    class V8Engine extends AbstractEngine {}
    class AudiV8Engine extends V8Engine {}
    
    • AbstractEngine is an abstract entity and is therefore not a leaf.
    • V6Engine is a final class. It can't have subclasses and is a leaf.
    • V8Engine is not final and has a subclass (AudiV8Engine) and is not a leaf.
    • AudiV8Engine is not final, but has no subclasses and is also a leaf.

    Note that Doctrine entities can't be final so that might be a reason that they're not mentioning the word final.

    2. What if I use (Single or Class) Table Inheritance as a target entity?

    According to the docs, Doctrine cannot create proxy instances if you have a relationship with non-leaf entity. This may cause a performance penalty, but it depends on your situation how big this issue is.

    In one of my projects I'm using Table Inheritance (Organisation as a base class with subclasses Customer and Supplier). In most cases the target-entity is either Customer or Supplier, but in some cases the target-entity is Organisation. It's one of the most important entities in my project and I haven't experienced performance issues.

    So based on the documentation and my own experience: you can use Table Inheritance as a target entity, but if performance is very important, reconsider the usage of STI/CTI.