Symfony/Doctrine类表继承和外键为主键



我目前正在设计一个web应用程序与Symfony 2.5(和Doctrine 2.4.2),必须灵活,方便地插入新的模块/包。

所以我有一个实体(假设A),它与抽象类(B和C)有两个一对一的关联。未来的模块将实现两个抽象类中的一个。由于关联是一对一的,所以我将它们作为抽象类的ID,以便在我们知道A的实例ID时方便地访问它们

代码是这样的:

A类:

<?php
namespace MeTestBundleEntity;
use DoctrineORMMapping as ORM;
/**
 * @ORMTable()
 * @ORMEntity
 */
class A
{
  /**
   * @ORMColumn(name="id", type="integer")
   * @ORMId
   * @ORMGeneratedValue(strategy="AUTO")
   */
  private $id;
  /**
   * @ORMOneToOne(targetEntity="B", cascade={"all"}, mappedBy="a")
   * @ORMJoinColumn(name="id", referencedColumnName="a_id")
   */
  private $b;
  /**
   * @ORMOneToOne(targetEntity="C", cascade={"all"}, mappedBy="a")
   * @ORMJoinColumn(name="id", referencedColumnName="a_id")
   */
  private $c;
}

B类:

<?php
namespace MeTestBundleEntity;
use DoctrineORMMapping as ORM;
/**
 * @ORMTable()
 * @ORMEntity
 * @ORMInheritanceType("JOINED")
 * @ORMDiscriminatorColumn(name="discr", type="string")
 */
abstract class B
{
  /**
   * @ORMId
   * @ORMOneToOne(targetEntity="A", inversedBy="b")
   * @ORMJoinColumn(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为array, null在/vendor/doctrine/dbal/lib/doctrine/dbal/Schema/Index.php第95行

当我将InheritanceType和DiscriminatorColumn注释添加到类B和c时,错误就出现了。事情是它告诉我我的模式是有效的。

所以有人有任何线索,如果我做错了什么?或者这绝对是教条中的错误?你有什么其他的主意能带来至少和我现在的方案一样多的灵活性吗?

Elioty

编辑:我将拥有方更改为抽象类B和C,因为根据文档,拥有方是具有外键的一方,必须使用inversedBy属性。即使做了这些修改,我的模式仍然有效,同样的错误仍然发生。

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

编辑3:我和Doctrine开发团队的一个成员聊了聊,他告诉我这看起来肯定像个bug。

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

生成的模式。

另一方面,php app/console doctrine:schema:update --dump-sql命令不执行对模式的实际更新,尽管它可能会发现一些错误,但其他一些不会出现…

我不理解类b。这个(抽象)类的身份是一个OneToOne关系?无论如何,问题是,如果您不添加inheritanceType定义,Doctine将忽略@ORDId。当你添加这个继承类型定义教条将使属性'a'的主键B.此外,它将创建另一个名为'a_id'的属性,这将作为一个外键为未来的子类(扩展B)。关系不能被继承。

相关内容

  • 没有找到相关文章

最新更新