我目前正在使用 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 开发团队的一名成员聊天,他告诉我这绝对看起来像一个错误。错误报告在这里。