如何在包中提供映射信息但允许实体 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.
是否有一种明智的方法可以让捆绑包提供预映射的实体,同时允许消费应用程序根据需要覆盖它们?
版本信息
- PHP 5.4.16
- Symfony 2.6.4
- 学说(通用)2.4.2
如果您使用的是学说,则需要使用单一 table 继承或映射的超类。
这里是参考文档:
请注意,学说还有其他类型的继承,但它们并不完全适用于此用例。他们是:
如果您的用例不属于这些类别之一,您基本上需要从头开始创建自己的实体并自行处理所有关联、映射等。
我已经在 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.
是否有一种明智的方法可以让捆绑包提供预映射的实体,同时允许消费应用程序根据需要覆盖它们?
版本信息
- PHP 5.4.16
- Symfony 2.6.4
- 学说(通用)2.4.2
如果您使用的是学说,则需要使用单一 table 继承或映射的超类。
这里是参考文档:
请注意,学说还有其他类型的继承,但它们并不完全适用于此用例。他们是:
如果您的用例不属于这些类别之一,您基本上需要从头开始创建自己的实体并自行处理所有关联、映射等。