Как избавиться от ошибок проверки схемы при сопоставлении «один ко многим» с «присоединенным» дочерним классом в Doctrine? - PullRequest
1 голос
/ 06 ноября 2019

У меня есть абстрактный ContentItem класс, который является сущностью Doctrine с типом наследования JOINED. Он находится в отношениях многих к одному с сущностью BusinessAccount. BusinessAccount имеет отношения один-ко-многим с неабстрактными подклассами ContentItem, в частности TextItem, которые являются обратными по отношению к вышеупомянутому отношению многие-к-одному.

Вот код: (удалены несвязанные части)

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 */
abstract class ContentItem
{
    /**
     * @var BusinessAccount
     * @ORM\ManyToOne(targetEntity=BusinessAccount::class)
     */
    protected $businessAccount;
}

/*
 * @ORM\Entity
 */
class BusinessAccount
{
    /**
     * @var Collection<TextItem>
     * @ORM\OneToMany(targetEntity=TextItem::class, mappedBy="businessAccount")
     */
    private $textItems;
}

/*
 * @ORM\Entity
 */
class TextItem extends ContentItem
{
    // nothing interesting here
}

Идея состоит в том, чтобы гарантировать, что каждый дочерний класс ContentItem принадлежит к BusinessAccount, в то же время разделяя разных потомков на отдельные отношения на стороне BusinessAccount.

Этот код прекрасно работает, однако он не проходит проверку схемы с помощью команды doctrine:schema:validate Doctrine:

Mapping

[FAIL] Класс сущностиНедопустимое сопоставление App \ Application \ BusinessAccount:

  • Поле App \ Application \ BusinessAccount # textItems находится на обратной стороне двунаправленного отношения, но в указанном сопоставлении mappedBy в приложении целевого объекта\ Entity \ TextItem # businessAccount не содержит обязательный атрибут 'inversedBy = "textItems"'.

Мне кажется, что Doctrine правильно идентифицируетmany-to-one и one-to-many обозначают как две стороны одной ассоциации, но он хочет, чтобы я явно указал имя обратного свойства в ContentItem::$businessAccount. Я не могу этого сделать, поскольку существует несколько обратных свойств, по одному на каждый подкласс ContentItem.

. Я могу устранить эти ошибки, переместив свойство $businessAccount в подклассы ContentItem. Я не нахожу это решение удовлетворительным, потому что оно вводит дублирование кода, затрудняет гарантированное владение каждым подтипом ContentItem и перемещает внешние ключи в другие таблицы.

Я пытался переопределить $businessAccountсвойство в дочерних классах с указанным inversedBy, но оно не устраняет ошибку.

Есть ли чистое решение, которое позволило бы мне разрешить эти ошибки?

1 Ответ

1 голос
/ 07 ноября 2019

Я думаю, что вы могли бы сделать это с помощью Переопределения ассоциаций .

По сути, у вас будет правильное и полное сопоставление в родительской сущности (например, включая свойство inversed_by):

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 */
abstract class ContentItem
{
    /**
     * @var BusinessAccount
     * @ORM\ManyToOne(targetEntity=BusinessAccount::class, inversedBy="textItems")
     */
    protected $businessAccount;
}

А затем определите конкретное переопределение в дочерних элементах, когда вам это нужно:

/*
 * @ORM\Entity
 * @ORM\AssociationOverrides({
 *      @ORM\AssociationOverride(name="businessAccount",
 *          inversedBy="otherProperty"
 *      )
 * })
 */
class TextItem extends ContentItem
{
    // nothing interesting here
}
...