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; }
Many thanks for this entry and for your resource on the whole. I’ve just liked it.
How can I do it so that instead of inventory_id I have other filed.For example inventory?
In inventory_room table I mean
What do you mean?
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?
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?
Doctrine searches for “inventory_id” not for “inventory” in inventory_room table to insert primary key
Just change the name property to the correct field name:
/**
* @ORM\Id @ORM\Column(name=”inventory_id”)
* @ORM\GeneratedValue
* @var int
**/
protected $inventory_id;