如何在bundle中提供映射信息,但允许重写Entity类

时间:2015-03-09 20:18:05

标签: php symfony doctrine-orm

我已经在Symfony开发应用程序已有几年了,但还没有深入研究独立的软件包开发,而且它现在正在咬我。

我要做的是提供一些预先定义的实体,消费应用程序可以安装,但如果需要,可以使用自己的实体类覆盖。

以下是我提供的两个表格

的src /我/ CustomBundle /资源/配置/教义/ User.orm.xml

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="My\CustomBundle\Entity\User" table="user">
    <id name="id" type="integer" column="id">
      <generator strategy="IDENTITY"/>
    </id>
    <field name="username" type="string" column="username" length="16" nullable="false"/>
    <field name="email" type="string" column="email" length="255" nullable="true"/>
    <one-to-many field="properties" target-entity="My\CustomBundle\Entity\UserProperty" mapped-by="user" fetch="EAGER" />
  </entity>
</doctrine-mapping>

的src /我/ CustomBundle /资源/配置/教义/ User.orm.xml

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="My\CustomBundle\Entity\UserProperty" table="user_property">
    <indexes>
      <index name="fk_user_property_user1_idx" columns="user_id"/>
    </indexes>
    <unique-constraints>
      <unique-constraint columns="user_id,key" name="user_key_UNIQUE" />
    </unique-constraints>
    <id name="id" type="integer" column="id">
      <generator strategy="IDENTITY"/>
    </id>
    <field name="key" type="string" column="`key`" length="45" nullable="false"/>
    <field name="value" type="string" column="`value`" length="255" nullable="true"/>
    <many-to-one field="user" target-entity="My\CustomBundle\Entity\User" inversed-by="properties">
      <join-column name="user_id" referenced-column-name="id" nullable="false"/>
    </many-to-one>
  </entity>
</doctrine-mapping>

我只是使用这些工具从这些映射中自动生成实体类,所以我不打算为这些代码发布代码,因为它们非常容易预测。

当我尝试从另一个包中使用这些实体时,问题就出现了。例如。

的src /的appbundle /实体/ user.php的

<?php

namespace AppBundle\Entity;

use My\CustomBundle\Entity\User as BaseUser;

class User extends BaseUser {}

现在这总是会提示错误

[Doctrine\ORM\Mapping\MappingException]                                                                                           
  Class "AppBundle\Entity\User" sub class of "My\CustomBundle\Entity\User" is not a valid entity or mapped super class. 

如果我试图通知学说AppBundle\Entity\User是一个实体,那么

<?php

namespace AppBundle\Entity;

use My\CustomBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * User
 *
 * @ORM\Entity
 */
class User extends BaseUser {}

然后这也失败了

[Doctrine\DBAL\Schema\SchemaException]              
  The table with name 'database.user' already exists.

是否有一种理智的方式让捆绑包提供预先映射的entites,但也允许消费应用程序根据需要覆盖它们?

版本信息

  • PHP 5.4.16
  • Symfony 2.6.4
  • 学说(普通)2.4.2

1 个答案:

答案 0 :(得分:2)

如果您正在使用doctrine,则需要使用单表继承或映射的超类。

这里是参考文档:

Single Table Inheritance

Mapped Superlcass

请注意,doctrine具有其他类型的继承,但它们并不完全适用于此用例。他们是:

Class Table Inheritance

Overrides

如果您的用例不属于其中一个类别,则您基本上需要从头开始创建自己的实体并自行处理所有关联,映射等。