因为你想做的单表继承不是你需要的。
有两种选择:
1) MappedSuperClass(几乎直接来自文档)
您创建了一个MappedSuperClass(文档可以在6.1: Mapped Superclasses一章中找到),然后在该基类中添加这些公共字段。然后你从你的基(映射的超)类中扩展所有需要这些字段的类。
/**
* @MappedSuperclass
*/
class MappedSuperclassBase
{
/** @Column(type="datetime") */
protected $creationDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $creationUser;
/** @Column(type="datetime") */
protected $lastChangeDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="updated_by", referencedColumnName="id")
*/
protected $lastChangeUser;
// ... more fields and methods
}
/**
* @Entity
*/
class EntitySubClass extends MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private $id;
// ... more fields and methods
}
2) 你使用一个特质
您创建一个特征(或每个字段/关联的几个单独的特征),您在所有需要具有这些公共字段的类中使用。
trait BaseTrait
{
/** @Column(type="datetime") */
protected $creationDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $creationUser;
/** @Column(type="datetime") */
protected $lastChangeDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="updated_by", referencedColumnName="id")
*/
protected $lastChangeUser ;
// ... more fields and methods
}
/**
* @Entity
*/
class EntitySubClass
{
use BaseTrait;
/** @Id @Column(type="integer") */
private $id;
// ... more fields and methods
}
回答您的问题:
a) 在您可以阅读的文档中:
单表继承是一种继承映射策略,其中层次结构的所有类都映射到单个数据库表。为了区分哪一行代表层次结构中的哪种类型,使用了所谓的鉴别器列。
这意味着所有这些实体将共享一个公用表,这绝对不是您想要的。它可能会变成一个巨大的表(每个实体一行),从而减慢您的查询速度。除此之外,表中还将有所有不常用的字段列,对于没有这些字段的实体,这些列将为空 (null)。这也意味着那些非共享字段不能有null 约束。再次直接来自文档:
要使单表继承在您使用遗留数据库架构或自编写数据库架构的情况下工作,您必须确保所有不在根实体中但在任何不同的列中的列子实体必须允许空值。具有 NOT NULL 约束的列必须位于单表继承层次结构的根实体上。
这种继承仅对类似于巨大扩展的实体是必需的,不适合您在问题中讨论的示例。
b)您可以在通用模型(例如您的Application 文件夹)中添加基本实体(即MappedSuperClass)。