当一个子类没有额外属性时,Doctrine表类继承

时间:2011-08-12 09:04:48

标签: php inheritance doctrine-orm

我的映射存在问题。我无法让它发挥作用。我有一个像这样的抽象基类:

/**
 * @Entity
 * @Table(name="actions")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"FOO" = "FooAction", "BAR" = "BarAction", ...})
 */
abstract class AbstractAction
{
    ...
}

我有很多不同的行动,都有不同的领域。 E.g:

/**
 * @Entity
 * @Table(name="actions_foo")
 */
class FooAction extends AbstractAction
{
   ...
}

但我的一个动作(BarAction)除AbstractAction提供的字段外不需要任何额外的字段。但是我该如何映射呢?我尝试省略@Table,或使用与@Table相同的AbstractAction,但没有效果。

/**
 * @Entity
 * @Table(name="actions")
 */
class BarAction extends AbstractAction
{
   ...
}

省略@Table给我PDOException关于丢失的表格BarAction。使用基类的@Table给我:

PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

那么,我该如何映射呢?

编辑:到目前为止,我还尝试了两件事。

我尝试从@Entity删除@Table以及BarAction,希望通过这种方式不再需要数据库表。这不起作用。相反,我得到了这个错误:

Doctrine\ORM\Mapping\MappingException: Class BarAction is not a valid entity or mapped super class.

接下来,我尝试在我的数据库中创建一个只有一个外键列actions_bar的{​​{1}}表。然后我将id映射到它。这是有效的(耶!)但是有一个我根本不需要的额外SQL表会感到非常难过。

所以,还在寻找更好的方法......

5 个答案:

答案 0 :(得分:2)

也许这可以帮助或添加新的东西。这不是一个如何回答而只是简单地接受概念。

如果您考虑类并且您将模型理解为:AbstractAction,FooAction和BarAction,可能是因为您可以在子类上以不同的方式实现相同的方法或扩展某些父方法。

如果您选择使用表格来表示这些类,并选择“具有鉴别器属性的一体化表格”,我认为您没有问题。对于BarAction,您将注册discriminator =“BarAction”,它将被BarAction.php实体类重新命名。

另一方面,如果您选择使用不同的表,我认为每个“类”需要一个表。 BarAction表只包含AbstractAction的ID字段,但需要将您的数据“分类”(或区分)为FooAction。

总之,我认为代表三个类的三个表是一个很好的解决方案,尽管BarAction表只包含父表的“链接”。

答案 1 :(得分:2)

您正在使用joined继承模型(类表继承),它为父项和每个子项使用单独的表。如果未在子类中指定任何字段,则Doctrine将只创建一个仅包含ID字段的表。

父类只能使用一种类型的继承,即类表继承或单表继承。

在这种情况下,如果您不想让表中只包含id列,则需要更改数据模型。

答案 2 :(得分:0)

我认为您不必手动创建数据库中的表。

我有几乎相同的结构,我让Doctrine(2.3)完成这项工作。你必须在每个子类上放置@Entity et @Table。 错误     参数号无效:绑定变量数与令牌数不匹配 可能没有关系。它可能是一个缓存问题,你试过刷它吗?

答案 3 :(得分:0)

我也遇到了这个问题,但我只是在我的继承实体中添加了一些虚拟属性,认为它随时都有用。我知道这不是一个完美的想法,但它帮助我保持我的数据模型完整无缺,并让我有可能在未来的继承实体中拥有自己的属性。

答案 4 :(得分:0)

反应迟到,但对其他提出此问题的人可能有用。

将类“ AbstractAction”具体化,并在鉴别器映射中添加一个映射(您可能此时要重命名)

 * @DiscriminatorMap({"ABSTRACT" = "AbstractAction", "FOO" = "FooAction", "BAR" = "BarAction", ...})
 */
class AbstractAction
{

然后应将该表用于不需要其他列的行