Как создать отношение ManyToOne в одном классе с суперкартой - PullRequest
2 голосов
/ 14 января 2020

Я создаю простой CMS Bundle для моего безголового symfony бэкэнда, и я пытаюсь отобразить страницу на страницу с родителем и дочерним отношением (многие дочерние элементы к одному родителю), и у меня есть этот класс, сопоставленный суперклассу, чтобы создать повторно используемый код Это уменьшенный пример того, что я пытаюсь заархивировать:


use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass()
 */
class Test
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function getId()
    {
        return $this->id;
    }

    /**
     * @ORM\ManyToOne(targetEntity="Ziebura\CMSBundle\Entity\Test")
     */
    protected $parent;

    public function getParent()
    {
        return $this->parent;
    }

    public function setParent($parent)
    {
        $this->parent = $parent;
    }
}

Затем я расширяю этот класс как обычный объект для создания таблицы БД

<?php

namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Ziebura\CMSBundle\Entity\Test as BaseTest;

/**
 * @ORM\Table(name="test")
 * @ORM\Entity(repositoryClass="App\Repository\TestRepository")
 */
class Test extends BaseTest
{
}

Проблема это то, что я получаю это doctrine исключение

Column name `id` referenced for relation from App\Entity\Test towards Ziebura\CMSBundle\Entity\Test does not exist. 

Я не совсем понимаю, почему это вызывает эту ошибку, или я пытаюсь заархивировать то, что невозможно, я уже установил связи с сопоставленным суперклассы, но это было 2 или более столов, а не только один на. Я уже пытался создать поле $ children, но оно не сработало и все равно выдало ошибку выше. Кто-нибудь пытался создать что-то подобное? Я не смог найти ничего об этом в doctrine документах, нашел только, как отобразить 2 разных суперкласса. Я полагаю, что самым простым выходом было бы указать отношение в пространстве имен App, а не в Bundle, но это в значительной степени разрушает цель повторно используемого кода, если бы мне пришлось объявить, что в каждом проекте, который я использую, комплект. Я верю в стек, давайте разберемся с этим. Спасибо!

Ответы [ 2 ]

2 голосов
/ 15 января 2020

Давайте прочитаем Doctrine документы по этому поводу: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html#inheritance -mapping

Сопоставленный суперкласс - это абстрактный или конкретный класс, который предоставляет постоянное состояние сущности и информацию сопоставления для его подклассы, но который сам не является сущностью. Как правило, целью такого сопоставленного суперкласса является определение информации о состоянии и отображении, которая является общей для нескольких классов сущностей.

...

Сопоставленный суперкласс не может быть сущностью, это не устойчивые к запросу и постоянные отношения, определенные сопоставленным суперклассом, должны быть однонаправленными (только со стороны владельца). Это означает, что связи «один ко многим» вообще невозможны для сопоставленного суперкласса.

В соответствии с этим:

  • MappedSuperclass не может быть сущностью
  • Невозможно иметь отношение «один ко многим» - поэтому, если вы определяете ManyToOne для того же класса, он также создает OneToMany для того же класса, что, как вы читали выше, запрещено.
0 голосов
/ 14 января 2020

По какой-то причине только изменение полного пути объекта в BaseTest разрешило приложение, выдавшее исключение, и оно работает, если кто-то столкнется с той же проблемой, попробуйте изменить

    /**
     * @ORM\ManyToOne(targetEntity="Ziebura\CMSBundle\Entity\Test")
     */
    protected $parent;

    public function getParent()
    {
        return $this->parent;
    }

    public function setParent($parent)
    {
        $this->parent = $parent;
    }

на

    /**
     * @ORM\ManyToOne(targetEntity="Test")
     */
    protected $parent;

    public function getParent()
    {
        return $this->parent;
    }

    public function setParent($parent)
    {
        $this->parent = $parent;
    }

Если кто-то знает, почему так должно быть, я очень благодарен за комментарий к моему ответу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...