Search code examples
doctrine-ormdoctrineone-to-manysingle-table-inheritancebidirectional

Doctrine Single Table Inheritance and bidirectional OneToMany: columns not being generated


The data model:


The data model



The entities:

Pet:

/**
 * @ORM\Entity
 * @ORM\Table(name="pet")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="pet_type", type="string")
 */
abstract class Pet
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\OneToMany(
     *     targetEntity="Collar",
     *     mappedBy="pet",
     *     cascade={"persist", "remove"},
     *     orphanRemoval=TRUE
     * )
     * @ORM\JoinColumn(name="collars", referencedColumnName="id")
     */
    protected $collars;

    /**
     * @ORM\Column(type="integer")
     */
    protected $age;


}


Cat:

/**
 * @ORM\Entity
 * @ORM\Table(name="cat")
 */
class Cat extends Pet
{

    /**
     * @ORM\Column(type="decimal")
     */
    private $purringDecibels;
}


Collar:

/**
 * @ORM\Entity
 * @ORM\Table(name="collar")
 */
class Collar
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Pet", inversedBy="collars")
     * @ORM\JoinColumn(name="pet", referencedColumnName="id", nullable=false)
     */
    private $pet;

    /**
     * @ORM\Column(type="string", length="255")
     */
    private $color;
}


The problem:

The generated tables are fine except pet: It lacks the collars column, therefore the bidirectionality is broken. While the pet ids do get stored on the collar table, I cannot fetch collars from a pet (i.e. $pet->getCollars()) as it always returns an empty collection.

What am I missing out here?


PS:

  • The validate console helper says all (mapping & db) is OK.
  • Yes, I have my getters and setters (i.e. adders and removers)
  • I know about the infamous performance impact of the combination between a CTI and this kind of relationship.

Solution

  • You do not need to have a "collars" column on the pet table. It is a one-to-many relationship, so the only table that need to "know" about pets are the collar table.

    A bidirectional relationship does not mean you need two columns on two tables.

    Your map seems correct.