Reputation: 45
I'm writing a Symfony application which will be used by multiple customers. Some customers require extra functionality, so my idea is that I put all my standard functionality in BundleA, and place extra functionality in BundleB, which is only enabled for customers which require it.
One of the things I want to do in BundleB, is to extend an entity in BundleA, by adding an extra field.
My code currently looks something like this:
<?php
// BundleA/Model/Element.php
namespace BundleA\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class Element
{
// All shared fields defined here
}
<?php
// BundleA/Entity/Element.php
namespace BundleA\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="Element")
* @ORM\Entity
*/
class Element extends AbstractElement
{
}
<?php
// BundleB/Entity/BundleBElement.php
namespace BundleB\Entity\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="Element")
*/
class BundleBElement extends AbstractElement
{
/**
* @ORM\Column(name="mypage_id", type="integer")
*/
protected $mypageId;
}
If I try to dump the SQL for the above code, I get the following:
The table with name 'element' already exists.
Basically what I need I think, is some sort of config option which lets me configure which Element-class to use for the entity. Something like:
bundle:
element_class: BundleB\Entity\BundleBElement
but I'm unsure about how to implement such a config option.
All the customers have their own database, so there shouldn't be a issue of conflicting entities.
Upvotes: 1
Views: 1406
Reputation: 13107
What you want is single table inheritance:
<?php
// BundleA/Model/Element.php
namespace BundleA\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"a"="Element", "b"="BundleBElement"})
*/
abstract class Element
{
// All shared fields defined here
}
<?php
namespace BundleA\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Element extends AbstractElement
{
}
<?php
namespace BundleB\Entity\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class BundleBElement extends AbstractElement
{
/**
* @ORM\Column(type="integer")
*/
protected $mypageId;
}
Please note that the @Table
annotations were removed. (They are actually unnecessary for most use cases. Don't know why people always add them.)
Upvotes: 0
Reputation: 6379
Your having two table definitions. Try to delete the table definition in your Entity or use a different table name.
<?php
// BundleA/Model/Element.php
namespace BundleA\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class Element
{
// All shared fields defined here
}
<?php
// BundleA/Entity/Element.php
namespace BundleA\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="Element")
* @ORM\Entity
*/
class Element extends AbstractElement
{
}
<?php
// BundleB/Entity/BundleBElement.php
namespace BundleB\Entity\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="ElementB")
*/
class BundleBElement extends AbstractElement
{
/**
* @ORM\Column(name="mypage_id", type="integer")
*/
protected $mypageId;
}
If you wanna extend it, you might delete the table definition in your Entity A so you only have one table with the extended data:
<?php
// BundleA/Model/Element.php
namespace BundleA\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class Element
{
// All shared fields defined here
}
<?php
// BundleA/Entity/Element.php
namespace BundleA\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
class Element extends AbstractElement
{
}
<?php
// BundleB/Entity/BundleBElement.php
namespace BundleB\Entity\Entity;
use BundleA\Model\Element as AbstractElement;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="Element")
*/
class BundleBElement extends AbstractElement
{
/**
* @ORM\Column(name="mypage_id", type="integer")
*/
protected $mypageId;
}
Upvotes: 2