Have had some serious problems getting this working, but after a 4 hour head bashing session, we’ve cracked it.

CREATE TABLE inventory(
    inventory_id INT AUTO_INCREMENT,
    discriminator_column VARCHAR(20),
    category VARCHAR(50) NOT NULL,
    part_number VARCHAR(50) NOT NULL,
    PRIMARY KEY (inventory_id),
    KEY category_part_number (category, part_number),
    KEY discriminator_column (discriminator_column)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE inventory_room(
    inventory_id INT NOT NULL,
    rack_limit INT(6),
    room_type VARCHAR(25),
    KEY inventory_id (inventory_id),
    CONSTRAINT inventory_room_key FOREIGN KEY (inventory_id) REFERENCES inventory (inventory_id) 
        ON DELETE CASCADE 
        ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

You have to have a discriminator field so that Doctrine can connect the tables nicely when its joining them.

<?php
namespace Net\Model\Inventory;
use Doctrine\ORM\Mapping as ORM;

/**
 * Inventory entity
 *
 * @ORM\Entity(repositoryClass="Net\Repository\Inventory")
 * @ORM\Table(name="inventory")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discriminator_column", type="string")
 * @ORM\DiscriminatorMap({"inventory" = "AbstractItem", "inventory_room" = "Room"})
 *
 * @category Net
 * @package  Model
 */
abstract class AbstractItem
{
    /**
     * @ORM\Id @ORM\Column(name="inventory_id") @ORM\GeneratedValue
     * @var int
     */
    protected $inventory_id;

    /**
     * @ORM\Column(type="string")
     * @var string
     */
    protected $category;    

    /**
     * @ORM\Column(type="string")
     * @var string
     */
    protected $part_number;
 }

As you can see in the above class, we have a ORM\GeneratedValue field. This tells Doctrine that this field is an increment field. As this is a one-to-one relationship we do not need one in the inventory_room table as it will be joined on the inventory_id field.

In the next class, this is the child class that extends the abstract. So Doctrine will read the annotations at the top and see that its a joined table using the id field (inventory_id)

<?php
namespace Net\Model\Inventory;
use Doctrine\ORM\Mapping as ORM;

/**
 * Inventory Room entity
 * @ORM\Entity
 * @ORM\Table(name="inventory_room")
 *
 * @category Net
 * @package  Model
 */
class Room extends AbstractItem
{
    /**
     * @ORM\Column(type="string")
     * @var string
     */
    protected $room_type;

    /**
     * @ORM\Column(type="string")
     * @var string
     */
    protected $rack_limit;
}

By admin

8 thought on “Setting up Class Table Inheritance with Doctrine 2.0”
    1. Here what I need:
      class Room extends AbstractItem
      {
      /**
      * @ORM\Id
      */
      protected $inventory;

      /**
      * @ORM\Column(type=”string”)
      * @var string
      */
      protected $room_type;

      /**
      * @ORM\Column(type=”string”)
      * @var string
      */
      protected $rack_limit;
      }

      I need $inventory be the primary key, which is inventory_id in AbstractItem. I need this because I have ready db structure and my child table key field has different name than in parent table.Can doctrine do this?

      1. I don’t see why not. What happens when you use the sample you’ve provided?

        Is the table called inventory and the primary key field inventory?

  1. Just change the name property to the correct field name:

    /**
    * @ORM\Id @ORM\Column(name=”inventory_id”)
    * @ORM\GeneratedValue
    * @var int
    **/
    protected $inventory_id;

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.