Symfony2 使用父级中的一个字段和具有不同注释/映射的扩展实体

Posted

技术标签:

【中文标题】Symfony2 使用父级中的一个字段和具有不同注释/映射的扩展实体【英文标题】:Symfony2 using one field in parent and extended Entitiy with different annotations/mappings 【发布时间】:2013-07-15 12:52:09 【问题描述】:

我遇到了问题,希望能得到专家的帮助。

我有实体:

产品

// src/Acme/DemoBundle/Entity/Product.php

/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product

   ...
   /**
     * @ORM\Column(name="file_uuid", unique=true, nullable=true)
     * @ORM\OneToOne(targetEntity="Acme\DemoBundle\Entity\File")
     * @ORM\JoinColumn(name="file_uuid", referencedColumnName="uuid")
     *
     */
    protected $file;

    /**
     * @ORM\OneToMany(targetEntity="Acme\DemoBundle\Entity\Image", mappedBy="product")
     *
     * @var ArrayCollection Collection of Image entities
     */
    protected $images;
    ...

文件

// src/Acme/DemoBundle/Entity/File.php

/**
 * @ORM\Entity
 * @ORM\Table(name="product_files")
 */
class File

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

    /**
     * @ORM\Column(name="uuid", type="string", length=64)
     */
    protected $uuid;

    /**
     * @ORM\Column(name="product_id")
     */
    protected $product;

    ...

图片

// src/Acme/DemoBundle/Entity/Image.php

/**
 * @ORM\Entity
 * @ORM\Table(name="product_images")
 */
class Image extends File


    /**
     * @ORM\ManyToOne(targetEntity="Acme\DemoBundle\Entity\Product", inversedBy="images")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    protected $product;

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

    ...

我的 sql 正确:

product_files
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| uuid        | varchar(64)  | NO   |     | NULL    |                |
| product_id  | varchar(255) | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+


product_images
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| uuid        | varchar(64)  | NO   |     | NULL    |                |
| product_id  | varchar(255) | NO   |     | NULL    |                |
| extension   | varchar(64)  | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

但是当我运行我的应用程序时,我遇到了一个错误:

An exception has been thrown during the rendering of a template ("Notice: Undefined index: product in .../vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1575") in AcmeDemoBundle:Product:edit.html.twig at line 24.

我哪里错了?

在 edit.html.twig 中我只是想显示产品图片。

我可以避免从 $product文件 实体注释中删除此问题:

@ORM\Column(name="product_id")

但是,在 doctrine:schema:update 之后,我失去了 product_images 表中的 product_id 字段。

我想要什么:

每个产品有一个文件 每个产品有多个图像

【问题讨论】:

您在 product_file 中的产品字段应该是与 product_id 的反向 OneToOne 而非列,请参阅:docs.doctrine-project.org/en/2.0.x/reference/… @Coussinsky 我也想拥有这个专栏。因为我想通过product_id查找文件。反正。如果我做你的改变: File /** * @ORM\OneToOne(targetEntity="Acme\DemoBundle\Entity\Product", mappedBy="file") / protected $product;和产品 /* * @ORM\Column(name="file_uuid") * @ORM\OneToOne(targetEntity="Acme\DemoBundle\Entity\File", inversedBy="product") * @ORM\JoinColumn( name="file_uuid", referencedColumnName="uuid") */ protected $file;我在两个表中都丢失了 product_id 字段。 当你处于两个实体之间的关系中时,你不能有@ORM\Column 注释。教义会自己处理。只需为关系添加注释,更新您的架构即可! @Coussinsky 正如你所说,我已经添加了。但现在教条:模式:更新从'product_images'中删除了'product_id' 为什么你的图片实体会扩展文件?您在产品和文件之间有一个 OneToOne,然后在产品和扩展文件的图像之间有一个 ManyToOne。我不确定,但看起来很奇怪。 【参考方案1】:

好的,我明白了。

问题是无法覆盖关系,因为我正在尝试非规范化我的数据库。

因此,为了实现我想要的学说,我提供了 3 种正确的方法:

创建一个不是实体的超类,包含我需要的所有属性,然后创建实体扩展它并描述我需要的所有关系; 创建一个“单表”映射。当您可以将 1 个表用于具有鉴别器列的多个实体时,该鉴别器列将确定应加载的实体; 和“映射超类”,其中您将拥有一个包含基本字段集的基表和一个仅包含扩展字段的扩展表和一个引用基表的额外字段 ID;

希望有人能避免花时间在发现同样的事情上。

链接:

Inheritance mapping

【讨论】:

以上是关于Symfony2 使用父级中的一个字段和具有不同注释/映射的扩展实体的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS - 在 Chrome 中选择文本触发父级中的 ng-click

垂直对齐具有高度自动和最小高度设置的父级中的div?

如何选择具有特定类的最后一个元素,而不是父级中的最后一个子元素?

仅展开父级中的子级 div

jQuery:在父级中选择具有类名的内部和外部第一个元素

GraphQL 解析器可以强制检索父级中的参数吗?