目前,我们正在使用 Zend Framework 2 和 Doctrine 2 开发一个非常灵活和模块化的应用程序。在这个应用程序中,有多个 Doctrine 实体,例如,假设实体 Product
在模块 Products
.这个模块Products
是产品管理的基本/默认模块。
我们希望能够创建自定义 Products
客户模块 (XProducts
)。因此我创建了一个新实体 XProduct
(带有一些额外的字段)扩展 Product
.
因此,如果启用了自定义模块,我想使用 XProduct
否则 Product
,但从不在一起(在同一个项目中)。
如果我用 @Entity 注释两个实体,它会部分工作;例如 findAll
完美运行,但 find
不起作用:创建的 SELECT 语句包含正确的列,但 WHERE 子句是错误的。例如:
SELECT t1.id AS id2, t1.name AS name3 FROM products t1 WHERE t0.id = ?
我猜
t1
代表 ProductX
和 t0
对于 Product
但我无法弄清楚为什么这些列是正确的( t1
)但 where 子句不是( t0
)。我知道 Doctrine 提供了单表继承来实现继承,但因此必须有一个 DiscriminatorColumn 并在基本/默认实体处定义 DiscriminatorMap。这不适合我们,因为如果我们为客户添加新的自定义模块(这不是我们想要的......),我们需要更改我们的基本/默认模块。
有没有人知道解决这个问题的线索?谢谢!
最佳答案
我终于解决了这个问题。对于所有默认/基类,我创建了一个额外的抽象 MappedSuperclass(如 Jurian Sluiman 所述)。例如,对于特定的 Product
客户的实体我需要以下内容:
为了解决 MappedSuperclass 上的关联问题,我引用了抽象类,例如:
@ORM\OneToOne(targetEntity="ProductManagement\Entity\AbstractProduct")
然后我使用 Doctrine 的 EntityResolver(参见 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/resolve-target-entity-listener.html)将抽象类(或接口(interface))关联映射到真实实体(取决于配置):
'entity_resolver' => array(
'orm_default' => array(
'resolvers' => array(
// Note: Use only one
'ProductManagement\Entity\AbstractProduct' => 'ProductManagement\Entity\Product', // Default
'ProductManagement\Entity\AbstractProduct' => 'XProductManagement\Entity\XProduct', // For customer X
)
)
)
这样我就可以为我的客户用特定实体覆盖我的实体,而无需更改默认/基本模块和实体(这正是我正在寻找的)。
关于inheritance - 教义继承替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17588682/