Как отобразить внешний ключ на объекте как поле и отображение в Doctrine? - PullRequest
0 голосов
/ 31 мая 2018

Справочная информация (короткая версия): приложение Symfony4, в котором я использую пользовательский уровень данных поверх уровня сущности доктрины, чтобы уровень бизнес-логики не зависел от схемы базы данных.Это не изменчиво на данный момент.

В некоторых случаях проще использовать внешний ключ, сопоставленный как поле:

/**
 * @var string
 *
 * @ORM\Column(name="article_id", type="string")
 */
protected $articleId;

, но в других случаях для того же объекта мне нужно соотношение:

/**
 * @var Article
 *
 * @ORM\OneToOne(targetEntity="Article")
 * @ORM\JoinColumn(name="article_id", referencedColumnName="id")
 */
protected $article;

чтобы не иметь одну и ту же сущность в 2-х экземплярах, я добавил приведенные выше фрагменты в одном классе.Если я гидратирую отношение, все работает хорошо ($ articleId игнорируется), но если указан только $ articleId, а $ article равен null, doctrine вставит в DB null для внешнего ключа.

1 Ответ

0 голосов
/ 31 мая 2018

Я нашел возможное решение: я анализирую метаданные класса, и если в $class->associationMappings['joinColumnFieldNames'] существуют поля, которые у меня также есть как поля в объекте, я удаляю сопоставление ассоциации:

doctrine /orm / lib / Doctrine / ORM / UnitOfWork.php

private function doMerge($entity, array &$visited, $prevManagedCopy = null, array $assoc = [])
{
    $oid = spl_object_hash($entity);

    if (isset($visited[$oid])) {
        $managedCopy = $visited[$oid];

        if ($prevManagedCopy !== null) {
            $this->updateAssociationWithMergedEntity($entity, $assoc, $prevManagedCopy, $managedCopy);
        }

        return $managedCopy;
    }

    $class = $this->em->getClassMetadata(get_class($entity));

    /* Code that I added */
    foreach ($class->associationMappings as $key => $mapping) {
        $joinColumns = $mapping['joinColumnFieldNames'] ?? [];

        if (array_intersect($joinColumns, $class->getColumnNames())) {
            unset($class->associationMappings[$key]);
            unset($class->reflFields[$key]);
        }
    }

    /* .... */

}

Этично ли это делать?

...