Sonata Admin 自引用关系错误

Sonata Admin Self Referencing relation Error

如果我在管理员中启用父字段,我会收到一个奇怪的错误:当前字段 parent 未链接到管理员。请为目标实体创建一个:``

这是我有问题的 MenuItem 实体:

namespace App\Entity;

use App\Util\TranslationUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="cms_menu_items")
 */
class MenuItem {

    public function __construct() {
        $this->children = new ArrayCollection();
    }

    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @return string
     */
    public function getId(): string { return $this->id ?: '' ; }

    // more fields ...

    /**
     * @var array|ArrayCollection
     * @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
     */
    protected $children = [];

    public function getChildren(): Collection { return $this->children; }

    /**
     * Add email
     *
     * @param MenuItem $child
     * @return MenuItem
     */
    public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }

    /**
     * Remove MenuItem
     *
     * @param MenuItem $child
     * @return MenuItem
     */
    public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }


    /**
     * Many Categories have One Category.
     * @ORM\Column(nullable=true)
     * @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    protected $parent;
    public function getParent(): ?MenuItem { return $this->parent; }
    public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }



    /**
     * @ORM\ManyToOne(targetEntity="Page")
     * @ORM\JoinColumn(name="page", referencedColumnName="id")
     */
    protected $page;
    public function getPage() : ?Page { return $this->page; }
    public function setPage($page) : MenuItem { $this->page = $page; return $this; }

}

还有管理员 Class,工作一尘不染,除非我启用父字段:

<?php

namespace App\Admin;

use App\Entity\MenuItem;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;


class MenuItemAdmin extends AbstractAdmin {

    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper
            ->add('ident', TextType::class, ['required' => false])
            ->add('label', TextareaType::class, [
                'attr' => ['rows' => 6]
            ])
            ->add('page', ModelAutocompleteType::class, [
                'required' => true,
                'property' => ['title', 'id']
            ])


            // this field below is throwing the above mentioned error

            ->add('parent', ModelAutocompleteType::class, [
                'required' => false,
                'property' => ['ident', 'label']
            ])
        ;
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper) {
        $datagridMapper
            ->add('id')
            ->add('ident')
            ->add('label')
        ;
    }

    protected function configureListFields(ListMapper $listMapper) {
        $listMapper
            ->addIdentifier('id')
            ->add('ident')
            ->add('label')
            ->add('page')
            ->add('parent')

        ;
    }
}

如果能帮助我指明正确的方向,我们将不胜感激。非常感谢!

看来我在 Doctrine ORM 数据库注释中犯了一个错误,因此 Sonata Admin 无法正确 link 该字段。

最终我尝试了 运行 bin/console doctrine:schema:validate 并得到了以下错误:

 [FAIL] The entity-class App\Entity\MenuItem mapping is invalid:
 * The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which is not defined as association, but as field.
 * The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which does not exist.

在我将自引用 OneToMany 关系的菜单项注释更改为以下代码后,效果非常好:)

class MenuItem {

   // [...] same as above

   /**
     * @var array|ArrayCollection
     * @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
     */
    protected $children = [];

    public function getChildren(): Collection { return $this->children; }

    /**
     * Add email
     *
     * @param MenuItem $child
     * @return MenuItem
     */
    public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }

    /**
     * Remove MenuItem
     *
     * @param MenuItem $child
     * @return MenuItem
     */
    public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }


    /**
     * Many Categories have One Category.
     * @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
     */
    protected $parent;
    public function getParent() : ?MenuItem { return $this->parent; }
    public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }


}