php - Doctrine :具有复合键的实体之间的 ManyToX 关系

标签 php mysql symfony doctrine-orm doctrine

我有三个实体,我们称它们为SiteCategoryTag。在此场景中,CategoryTag 具有从 Site 实体生成的复合 ID 和不唯一的外部 ID(site id 一起是唯一的)。 CategoryTag 之间存在多对多关系。 (尽管我的问题也可以通过 ManyToOne 关系重现。)

Site 实体:

/**
 * @ORM\Entity
 */
class Site
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $name;
}

类别实体:

/**
 * @ORM\Entity
 */
class Category extends AbstractSiteAwareEntity
{
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="Tag")
     */
    private $tags;
}

Tag 实体:

/**
 * @ORM\Entity
 */
class Tag extends AbstractSiteAwareEntity
{
    /**
     * @ORM\Column(type="string")
     */
    private $name;
}

最后两个实体继承自 AbstractSiteAwareEntity 类,该类定义了复合索引:

abstract class AbstractSiteAwareEntity
{
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Site")
     */
    public $site;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    public $id;
}

作为 ManyToOne 关系的示例,让我们想象一个 Post 实体,它具有自动增量 ID 和对 Category 的引用:

/**
 * @ORM\Entity
 */
class Post
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    public $id;

    /**
     * @ORM\ManyToOne(targetEntity="Category")
     */
    private $category;

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

    /**
     * @ORM\Column(type="string")
     */
    private $content;
}

使用 bin/consoledoctrine:schema:update --dump-sql --force --complete 更新架构时,出现以下异常:

An exception occurred while executing 'ALTER TABLE category_tag ADD CONSTRAINT FK_D80F351812469DE2 FOREIGN KEY (category_id) REFERENCES Category (id) ON DELETE CASCADE':

SQLSTATE[HY000]: General error: 1005 Can't create table xxxxxxx.#sql-3cf_14b6 (errno: 150 "Foreign key constraint is incorrectly formed")

我不确定可能出了什么问题……我的实体定义是否有错误?或者这是一个 Doctrine 错误?

注意:我在 Symfony 3.4 上使用doctrine/dbal 2.6.3。

最佳答案

您必须在注释中定义连接列才能使其正常工作:

对于多对一关系:

/**
 * @ORM\ManyToOne(targetEntity="Tag")
 * @ORM\JoinColumns({
 *     @ORM\JoinColumn(name="tag_site_id", referencedColumnName="site_id"),
 *     @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
 * })
 **/
protected $tag;

对于多对多关系:

/**
 * @ORM\ManyToMany(targetEntity="Tag")
 * @ORM\JoinTable(name="category_tags",
 *      joinColumns={
 *     @ORM\JoinColumn(name="category_site_id", referencedColumnName="site_id"),
 *     @ORM\JoinColumn(name="category_id", referencedColumnName="id")
 *     },
 *      inverseJoinColumns={
 *     @ORM\JoinColumn(name="tag_site_id", referencedColumnName="site_id"),
 *     @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
 *     }
 *      )
 **/
 protected $tags;

工作原理:创建 2 列作为外键引用复合外键。

注意:在“@ORM\JoinColumn”设置中:

  • “referencedColumnName”设置是相关表上的 id 列名称,因此它应该已经存在。

  • “name”是存储外键并要创建的列名称,在ManyToOne的情况下,它不应与实体的任何列冲突。

joinColumns 定义的顺序很重要。复合外键应以在引用表中具有索引的列开头。在这种情况下,“@ORM\JoinColumn”到“site_id”应该是第一个Reference

关于php - Doctrine :具有复合键的实体之间的 ManyToX 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49383754/

相关文章:

php - symfony + Doctrine 帮助

mysql - Sf3 Docker-compose : [2002] Connection refused

php - React前端服务器和PHP/Symfony后端服务器之间共享 session

返回错误 SUM 的 Mysql 查询问题

PHP PDO 多选查询始终删除最后一个行集

php - 子目录的 URL 无法正确重写

php - 在 PHP 中将一种日期格式转换为另一种日期格式

mysql - 在选择中选择值

php - swiftmailer 动态附加 Symfony

php - Mac CLI PHP ini 文件位置