如何在包中提供映射信息但允许实体 class 被覆盖

How to provide mapping info in bundle but allow Entity class to be overriden

我已经在 Symfony 中开发应用程序几年了,但还没有深入研究独立的捆绑开发,现在它让我很头疼。

我想做的是提供一些预定义的实体,消费应用程序可以安装这些实体,然后在需要时用它们自己的实体覆盖 类。

这是我随捆绑包提供的两个表格

src/My/CustomBundle/Resources/config/doctrine/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/My/CustomBundle/Resources/config/doctrine/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/Entity/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.

是否有一种明智的方法可以让捆绑包提供预映射的实体,同时允许消费应用程序根据需要覆盖它们?

版本信息

如果您使用的是学说,则需要使用单一 table 继承或映射的超类。

这里是参考文档:

Single Table Inheritance

Mapped Superlcass

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

Class Table Inheritance

Overrides

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