我正在尝试创建一个简单的多态属性表,该表可以存储不同类型对象的键值对。使用单表继承,这是我当前的配置:
/**
* @Entity @Table(name="attributes")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="subject", type="string")
* @DiscriminatorMap({"page" = "PageAttribute", "product" = "ProductAttribute"})
*/
class PageAttribute
{
/**
* @ManyToOne(targetEntity="Page", inversedBy="attributes")
* @JoinColumn(name="subject_id", referencedColumnName="id")
*/
private $page;
}
/**
* @Entity @Table(name="attributes")
*/
class ProductAttribute extends PageAttribute
{
/**
* @ManyToOne(targetEntity="Product", inversedBy="attributes")
* @JoinColumn(name="subject_id", referencedColumnName="id")
*/
private $product;
}
问题是加载此架构时,会创建subject_id列,并使用链接到pages表的外键约束。
有没有办法阻止这个约束,以便subject_id可以用于所有外键?否则,我必须为每种类型的对象都有一个列,我试图避免使用。
答案 0 :(得分:1)
我有同样的问题。以下是我如何解决它:
/**
* @Entity @Table(name="attributes")
*/
class ProductAttribute extends PageAttribute
{
public static function getSubject() {
return 'product';
}
/**
* @ManyToOne(targetEntity="Product", inversedBy="attributes")
* @JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
}
换句话说,不是使用subject_id来引用所有实体,而是为每种类型的实体使用单独的连接列。然后,您可以使用静态函数来获取“主题”列的参数名称。
例如:
$subject = $genericPageAttribute->{$genericPageAttribute::getSubject()};
在这种情况下会返回“Product”的实例。
为了使这个解决方案更好,我建议编写一个所有“主题”都可以实现的界面。
我不确定这是否会涵盖所有情况,但到目前为止似乎对我来说还不错。
让我知道它是如何工作的(或不是)!