I have an entity which I want to use as a base class for other entities (unknown at this time) and I need to store relationships in the base entity:
/**
* @ORM\Entity
* @ORM\Table(name="CMS_content")
*/
class BaseContent {
/**
* @ORM\ManyToOne(targetEntity="BaseContent")
* @ORM\JoinColumn(name="parent", referencedColumnName="id", unique=false)
*/
protected $parent;
/**
* @ORM\ManyToOne(targetEntity="ContentType")
* @ORM\JoinColumn(name="content_type", referencedColumnName="id", unique=false)
*/
protected $contentType;
...
};
/**
* @ORM\Entity
* @ORM\Table(name="CMS_whateverSpecializedContent")
*/
class WhateverSpecializedContent extends BaseContent {};
I cannot use@ORM\InheritanceType("JOINED")
because I want to be able to create arbitrary number of subclasses later without touching the base class. I also need to have the base class in a separate database table so the relationship would make sense.
What other options do I have to manage these kind of structure?
Instead of using entity inheritance I ended up using the delegate design pattern. Both Content
and BaseContent
implements a common interface and the BaseContent
delegate the functionality to a joined Content entity.
Now every subclass of this BaseContent will have a joined Content entity and can be used where an IContent is expected.
interface IContent {...}
/**
* @ORM\Entity
* @ORM\Table(name="CMS_content")
*/
class Content implements IContent {
/**
* @ORM\ManyToOne(targetEntity="BaseContent")
* @ORM\JoinColumn(name="parent", referencedColumnName="id", unique=false)
*/
protected $parent;
/**
* @ORM\ManyToOne(targetEntity="ContentType")
* @ORM\JoinColumn(name="content_type", referencedColumnName="id", unique=false)
*/
protected $contentType;
...
};
/**
* @ORM\Entity
* @ORM\Table(name="CMS_whateverSpecializedContent")
*/
class WhateverSpecializedContent extends BaseContent {};
/**
* @ORM\MappedSuperclass
*/
abstract class BaseContent implements IContent {
/**
* @ORM\OneToOne(targetEntity="Content", cascade={"persist", "merge", "remove"})
* @ORM\JoinColumn(name="content", referencedColumnName="id", unique=false)
*/
private $content;
public function implementedMethod() {
$this->content->implementedMethod();
}
};