在奏鸣曲中定义扩展实体

Defining extended entities in sonata

我有一些基本实体,它定义了所有(或至少大多数)其他实体应该具有的一些字段。看起来像:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;


/**
 * @ORM\Entity()
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks()
 */
abstract class BaseEntity {

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

    /**
     * @ORM\Column(type="boolean")
     */
    protected $published;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $createdAt;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $updatedAt;



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

等等...getter 和 setter。

然后我有实体,即 ArticleCategory 扩展了 BaseEntity:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ArticleCategoryRepository")
 */
class ArticleCategory extends BaseEntity
{

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;
        return $this;
    }
}

所以,它只是添加了一个额外的字段 - 标题。

然后,我有基础管理员 class:

namespace App\Admin;

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

class BaseAdmin extends AbstractAdmin
{

    /**
     * @param BaseEntity $entity
     */
    public function prePersist($entity)
    {
        $now = new \DateTime();
        $entity->setCreatedAt($now);
        $entity->setUpdatedAt($now);
        $entity->setPublished(true);
    }
}

然后是该 ArticleCategory 实体的管理员 class:

namespace App\Admin;

use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;

final class ArticleCategoryAdmin extends BaseAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('title', TextType::class);
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('title');
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('title');
    }
}

问题是当我转到奏鸣曲列表页面而不是显示 ArticleCategory 类型中的所有实体时,我收到 sql 错误:

'field list'

中的未知列 'b0_.id'

查询如下所示:

SELECT b0_.id AS id_0, b0_.published AS published_1, b0_.created_at AS created_at_2, b0_.updated_at AS updated_at_3, a1_.title AS title_4 
FROM article_category a1_ 
WHERE a1_.id IN (?, ?) 
ORDER BY a1_.id ASC' with params [2, 3]

So sonata 正在从正确的 table (article_category) 获取数据并为其创建别名 "a1_" 并且所有直接在 ArticleCategory(标题)中的字段都被很好地收集,使用该别名。 但是属于基础 class (BaseEntity) sonata 的所有其他字段都试图通过一些 un-existing 别名 "b0_" 获取,当然查询失败。

知道如何解决这个问题吗?如何告诉奏鸣曲所有字段都属于同一个 table 即使它们属于 2 个实体 classes?

找到问题了。在定义基础实体的开始我有:

/**
 * @ORM\Entity()
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks()
 */

这是不正确的,因为 "Entity()" 行。那必须被删除。它不能同时是实体和映射晚餐 class。

/**
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks()
 */