Setting up Class Table Inheritance with Doctrine 2.0

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;
}

8 comments on “Setting up Class Table Inheritance with Doctrine 2.0

  1. Vincent Lucia November 25, 2011 3:48 pm

    Many thanks for this entry and for your resource on the whole. I’ve just liked it.

  2. bekaurmich November 27, 2012 10:45 am

    How can I do it so that instead of inventory_id I have other filed.For example inventory?

    • bekaurmich November 27, 2012 10:46 am

      In inventory_room table I mean

  3. admin November 27, 2012 11:06 am

    What do you mean?

    • bekaurmich November 28, 2012 5:51 am

      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?

      • admin November 28, 2012 12:07 pm

        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?

  4. bekaurmich November 29, 2012 4:13 am

    Doctrine searches for “inventory_id” not for “inventory” in inventory_room table to insert primary key

  5. admin November 29, 2012 10:42 am

    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.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

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