我对Doctrine ORM又称STI的单表继承映射存在以下问题。
似乎从STI实体到另一个实体的oneToMany关联似乎是不可能的。
我有2个实体客户和供应商,字段非常相似。这就是为什么我想在Doctrine中使用单表继承选项来在一个表中使用简单的“类型”列来获取这两个实体,以指示该行属于哪个实体。 AbstractBusiness类将作为这两个实体的基类。
考虑AbstractBusiness的这个实体映射。
Axelvnk\CRMBundle\Entity\AbstractBusiness:
type: entity
table: axelvnk_crm_business
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: type
type: string
discriminatorMap:
customer: Axelvnk\CRMBundle\Entity\CustomerInterface
supplier: Axelvnk\CRMBundle\Entity\SupplierInterface
id:
id:
type: guid
generator:
strategy: UUID
fields:
vatNumber:
type: string
label:
type: string
oneToOne:
billingAddress:
targetEntity: Axelvnk\CRMBundle\Entity\AddressInterface
joinColumn:
name: billing_address_id
referencedColumnName: id
cascade: ["all"]
oneToMany:
addresses:
targetEntity: Axelvnk\CRMBundle\Entity\AddressInterface
mappedBy: business
cascade: ["all"]
这将是Customer实体的映射
Axelvnk\CRMBundle\Entity\Customer:
type: entity
这将是供应商实体的映射
Axelvnk\CRMBundle\Entity\Supplier:
type: entity
目前暂无其他领域。但这对这个问题没有任何影响。
现在,AbstractBusiness :: billingAddress属性引用了Address实体的实例。哪个映射如下:
Axelvnk\CRMBundle\Entity\Address:
type: entity
table: axelvnk_crm_address
id:
id:
type: guid
generator:
strategy: UUID
fields:
streetAndNumber:
type: string
city:
type: string
manyToOne:
business:
targetEntity: Axelvnk\CRMBundle\Entity\AbstractBusiness
inversedBy: addresses
joinColumn:
name: business_id
referencedColumnName: id
正如您所看到的,Address :: business属性引用回STI实体,即AbstractBusiness。这可以是供应商也可以是客户,具体取决于拥有方。
我希望学说能够解决哪个实体类水合,因为它知道AbstractBusiness是一个STI实体并且鉴别器映射到位。在使用地址表中的business_id查询业务表之后,它应该能够根据地址表中的“类型”列找出类,对吧?但显然它没有。我无法映射回STI实体,因为doctrine不能从Abstract类创建代理类,这是有道理的。
但我现在的问题是,映射回STI实体的正确方法是什么?或者这在Doctrine中是不可能的?
谢谢您的回答!
显然,在discriminatorMap中使用接口,然后使用doctrine目标实体解析器将这些接口替换为具体类,可以完美地保留实体,但是为了获取它们,它无法弄清楚要用什么类来补充...
所以解决方案:始终在discriminatorMap中使用具体类...
在github上有一个开放的问题,支持在鉴别器映射中解析类/接口,就像它对targetEntity属性一样:https://github.com/doctrine/orm/issues/7622