2

我目前正在使用 Symfony 2.5(和 Doctrine 2.4.2)设计一个 Web 应用程序,它必须灵活地轻松插入新的模块/捆绑包。

所以我有一个实体(比如说 A),它与抽象类(B 和 C)有两个一对一的关联。未来的模块将实现两个抽象类之一。由于关联是一对一的,因此我将它们设为抽象类的 ID,以便在我们知道 A 实例的 ID 时轻松访问它们

所以这是代码的样子:

A类:

<?php

namespace Me\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table()
 * @ORM\Entity
 */
class A
{
  /**
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  /**
   * @ORM\OneToOne(targetEntity="B", cascade={"all"}, mappedBy="a")
   * @ORM\JoinColumn(name="id", referencedColumnName="a_id")
   */
  private $b;

  /**
   * @ORM\OneToOne(targetEntity="C", cascade={"all"}, mappedBy="a")
   * @ORM\JoinColumn(name="id", referencedColumnName="a_id")
   */
  private $c;
}

B类:

<?php

namespace Me\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table()
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 */
abstract class B
{
  /**
   * @ORM\Id
   * @ORM\OneToOne(targetEntity="A", inversedBy="b")
   * @ORM\JoinColumn(name="a_id", referencedColumnName="id")
   */
  private $a;
}

我不会发布 C 类的代码,因为它与 B 类相同。

在我看来,一切似乎都很好。即使对于映射验证命令。事实上,当我执行时php app/console doctrine:schema:validate,它告诉我我的模式是有效的。但是,此命令然后尝试将我的架构与数据库中的架构进行比较,但此时它只是失败了。php app/console doctrine:schema:update --dump-sql以完全相同的方式失败。所以这很尴尬,因为它告诉我我的模式是有效的,但它不能正确使用它。

错误:

[ErrorException]
警告:array_keys() 期望参数 1 为数组,/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php 第 95 行中给出的 null

一旦我将 InheritanceType 和 DiscriminatorColumn 注释添加到类 B 和 C 中,就会出现错误。事情是它告诉我我的模式是有效的。

如果我做错了什么,有人知道吗?或者它绝对是 Doctrine 中的一个错误?您是否有任何其他想法可以带来至少与我当前解决方案一样多的灵活性?

艾略提

编辑:我将拥有方更改为抽象类 B 和 C,因为根据文档,拥有方是具有外键的一方,并且必须使用 inversedBy 属性。即使进行了这些更改,我的架构仍然有效,并且仍然会发生相同的错误。

EDIT2:如果我在 B(和 C)中创建另一个字段来保存实体的身份而不是一对一关联,则错误会消失,但它不再像我的有效模式。

EDIT3:我与 Doctrine 开发团队的一名成员聊天,他告诉我这绝对看起来像一个错误。错误报告在这里

4

1 回答 1

0

首先,该命令php app/console doctrine:schema:validate检查当前模式的有效性。当前模式是您最后一次调用命令生成的模式php app/console doctrine:schema:update --force

另一方面,该命令php app/console doctrine:schema:update --dump-sql不会对架构执行实际更新,尽管它可能会发现一些错误,而其他一些则不会出现......

我不明白B类。这个(抽象)类的身份是OneToOne关系?无论如何,如果您不添加继承类型定义,Doctine 将忽略 @ORD\Id。当您添加此继承类型定义时,Doctrine 将使属性“a”成为 B 的主键。它还将创建另一个名为“a_id”的属性,该属性将用作未来子类(B 的扩展)的外键。但是……关系不是遗传的。

希望这可以帮助...

于 2016-10-14T16:27:04.350 回答