4

我正在将 Symfony 与 Doctrine 一起使用。

为了解决我的问题,我想:

  • 或者当我扩展实体类时,我希望教义忽略父类的@entity 注释(将其视为@MappedSuperclass)
  • 或者(这个更可取)当我扩展实体类时,添加类似@MappedChildclass 的子类只是为了知道这个类是一个实体,但是在父类中实际实现和映射

让我们看看具体的问题:

我有 3 个捆绑包:

  • AppBridgeBundle
  • 用户包
  • ProfileBundle

UserBundle 和 UserProfile 必须解耦。AppBridgeBundle 是 2 个捆绑包之间的桥梁,它将耦合两者。

UserBundle 有UserEntity

/**
 * @ORM\Entity
**/
class UserEntity {

     /**
     * @var \Acme\UserBundle\Interfaces\ProfileData
     * @ORM\ManyToOne(targetEntity="Acme\UserBundle\Interfaces\ProfileData",
                      cascade={"persist"})
     * )
     */
    private $profileData;

     // ...
}

UserBundle有自己的接口ProfileData(解耦,我们只需要注入这个接口的实现)。

ProfileBundle 有ProfileEntity

/**
 * @ORM\Entity
**/
class ProfileEntity implements Acme\ProfileEntity\Interfaces\Profile {

     // properties ...

}

ProfileBundle 有自己的接口Profile(解耦)。

基本上 ProfileData 和 Profile 接口是相同的。

现在AppBridgeBundle 引入了Profile 和ProfileData 接口的Adapter来适配UserBundle 和ProfileBundle。

class ProfileAdapter  extends \Acme\ProfileBundle\Entity\ProfileEntity
                      implements   \Acme\UserBundle\Interfaces\ProfileData,
                                   \Acme\ProfileBundle\Interfaces\Profile {

}

config.yml接下来,我们在应用配置中注入我们的接口实现:

orm:
     resolve_target_entities:
          Acme\UserBundle\Interfaces\ProfileData: Acme\AppBridgeBundle\Entity\ProfileAdapter

现在,问题是当我更新教义架构时,它会抛出一个Acme\AppBridgeBundle\Entity\ProfileAdapter不是Entity的错误。

  • 如果我将 ProfileAdapter 标记为@Entity,它将创建 2 个单独的表 - 我不需要它

  • 如果我将 ProfileAdapter 标记为@Entity与 ProfileEntity 同名 -@Table('profileentity')那么它会给我一个错误table profile already exists

  • 如果我用它标记 ProfileEntity@ORM\MappedSuperclassremove @Entity从中注释 - 我将放弃 ProfileEntity 类的默认实现(因此它不能在没有桥的情况下工作)。

  • 如果我用它标记 ProfileEntity@InheritanceType("SINGLE_TABLE")会将不必要的鉴别器字段添加到我的表中。

有什么建议么?

4

2 回答 2

0

我认为诀窍是使用调度的学说“loadClassMetadata”事件。您可以在知道 ProfileEntity 继承的订阅者中跟踪此事件,并注入“@Entity”或“@MappedSuperclass”注释。

你可以在这里看到一个实现:https ://github.com/victoire/CmsBundle/blob/master/EventSubscriber/LoadMetadataSubscriber.php 在这个例子中,我动态地将启用的小部件注入到我的小部件实体的 discriminatorMap 中。我让您根据需要调整此代码。

于 2013-09-16T21:38:43.210 回答
0

有同样的问题,我用你的例子做了什么:

  • 搬到\Acme\ProfileBundle\Entity\ProfileEntity_\Acme\ProfileBundle\Model\ProfileEntity
  • 重新声明ProfileEntity类,abstract但保留所有 ORM 指令不变
  • 重新声明ProfileAdapter扩展新ProfileEntity模型
  • 标记ProfileAdapter@ORM\Entityonly,所有剩余的@ORM*指令都留在模型类中

优点:

  • 没有额外的表格
  • 没有额外的字段
  • 不用桥也能工作

缺点:

  • 有必要为每个新的 Bundle 安装创建实体扩展抽象模型
于 2014-02-06T10:38:38.717 回答