Ассоциация oneToMany для единого объекта наследования - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть следующая проблема с отображением наследования одной таблицы для Doctrine ORM aka STI.

Кажется, что невозможно связать oneToMany с объектом STI с другим объектом.

У меня есть 2 сущности Клиент и Поставщик , с очень похожими полями.Вот почему я хочу использовать опцию наследования одной таблицы в Doctrine, чтобы получить эти 2 сущности в одной таблице с простым столбцом типа, чтобы указать, к какой сущности принадлежит строка. AbstractBusiness класс будет служить базовым классом для этих 2 сущностей.

Рассмотрим это сопоставление сущностей для 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

Это сопоставление для сущности Supplier

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 в таблице адресов он должен иметь возможность определить класс на основе столбца «type» в таблице адресов, верно?Но, видимо, это не так.Я не могу отобразить обратно на сущность STI, потому что доктрина не может создавать прокси-классы из абстрактных классов, что, я думаю, имеет смысл.

Но теперь мой вопрос заключается в том, как правильно вернуться кИППП?Или это просто невозможно в Учении?

Спасибо за ваши ответы!

1 Ответ

0 голосов
/ 21 февраля 2019

Таким образом, очевидно, что использование интерфейсов вcriminatorMap, а затем использование распознавателя целевой сущности doctrine для замены этих интерфейсов конкретными классами прекрасно работает для сохранения сущностей, но для их извлечения невозможно определить, какой класс нужно гидрировать ...

Итак, решение: всегда использовать конкретные классы в respminatorMap ...

Существует открытая проблема в github для поддержки разрешения классов / интерфейсов в карте дискриминатора таким же образом, как это работает для targetEntity.свойства: https://github.com/doctrine/orm/issues/7622

...