Doctrine 2 - 多对一关系的外键不允许空值

Posted

技术标签:

【中文标题】Doctrine 2 - 多对一关系的外键不允许空值【英文标题】:Doctrine 2 - Disallow null value on foreign keys of ManyToOne relationships 【发布时间】:2011-09-02 10:57:53 【问题描述】:

我的一个实体中有一个多对一关系,如下所示:

class License 
    // ...
    /**
     * Customer who owns the license
     * 
     * @var \ISE\LicenseManagerBundle\Entity\Customer
     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="licenses")
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
     */
    private $customer;
    // ...


class Customer 
    // ...
    /**
     * Licenses that were at one point generated for the customer
     * 
     * @var \Doctrine\Common\Collections\ArrayCollection
     * @ORM\OneToMany(targetEntity="License", mappedBy="customer")
     */
    private $licenses;
    // ...

这会生成一个数据库架构,其中许可表的“customer_id”字段允许为空,这正是我不想要的。

这是我创建记录以证明它确实允许引用字段为空值的一些代码:

$em = $this->get('doctrine')->getEntityManager();
$license = new License();
// Set some fields - not the reference fields though
$license->setValidUntil(new \DateTime("2012-12-31"));
$license->setCreatedAt(new \DateTime());
// Persist the object
$em->persist($license);
$em->flush();

基本上,我不希望在没有客户分配的情况下保留许可证。是否需要设置一些注释,或者我应该只需要将 Customer 对象传递给我的许可证的构造函数?

我使用的数据库引擎是 mysql v5.1,我在 Symfony2 应用程序中使用 Doctrine 2。

【问题讨论】:

你有实际创建记录的代码吗?你在用 MySQL 吗? @abe-petrillo 我使用的是 MySQL 5.1。我已使用创建记录的代码示例更新了问题。 我自己发现的。根据the doctrine annotation reference,@Column@JoinColumn 注释有一个nullable 选项。将其设置为 false 会导致我想要的行为。 【参考方案1】:

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/annotations-reference.html#annref_joincolumn

nullable = false 添加到JoinColumn 注释中:

@ORM\JoinColumn(..., nullable=false)

【讨论】:

@ORM\JoinColumn(nullable=false) 使用yml 格式时,请注意将此属性添加到joinColumn 下,而不是关系名称下。我花了很长时间才找到它! 答案中的链接返回404 Not Found,需要更新 当前文档链接doctrine-project.org/projects/doctrine-orm/en/current/reference/…【参考方案2】:

只是发布因为@zim32 没有告诉我们应该把声明放在哪里,所以我不得不反复试验。

Yaml:

manyToOne:
    field:
        targetEntity: Entity
        joinColumn:
            name: field
            nullable: false
            referencedColumnName: id
        cascade: ['persist']

【讨论】:

【参考方案3】:

我找不到如何做到这一点的 XML 示例,所以我将把这个 sn-p 留在这里,以防其他人正在寻找它:

<many-to-one field="author" target-entity="User">
    <join-column name="author_id" referenced-column-name="id" nullable="false" />
</many-to-one>

namereferenced-column-name 是必需的,请参阅文档:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/xml-mapping.html#join-column-element

【讨论】:

以上是关于Doctrine 2 - 多对一关系的外键不允许空值的主要内容,如果未能解决你的问题,请参考以下文章

连接两个共享多对一关系的 SQL 表

如何向具有多对一关系的模型的 Django 管理员添加可排序的计数列?

一对多和多对一关系的区别

如何在 >2 个表上进行外部联接 (Oracle)

模板中具有多对一关系的Django模型

Doctrine2 多对一关联不会使用 JOIN 查询