使用接口的 Symfony2 关系会导致重复的表



我正在尝试将一个捆绑包中的实体与另一个捆绑包中的另一个实体相关联,以使第二个实体独立于第一个捆绑包,并能够重用它。

我正在遵循此文档和此StackOverflows答案。

在可重用的捆绑包中,我有一个文件夹,属于该文件夹的文件 a,界面如下:

namespace AcmeFolderBundleEntity;
/**
 * @ORMEntity
 */
class Folder implements FolderInterface
{
    // Has many files
}
namespace AcmeFolderBundleEntity;
interface FolderInterface
{
    // no methods here
}
namespace AcmeFolderBundleEntity;
/**
 * @ORMEntity
 */
class File
{
    // Belongs to one folder
}

在另一个捆绑包上只有一个类:

namespace AcmeNewBundleEntity;
use DoctrineORMMapping as ORM;
use AcmeFolderBundleEntityFolder as BaseFolder;
use AcmeFolderBundleEntityFolderInterface;
/**
 * @ORMEntity
 */
class Folder extends BaseFolder implements FolderInterface
{
    // Has many files
}

以及 config.yml 的 ORM 配置:

orm:
    auto_generate_proxy_classes: %kernel.debug%
    auto_mapping: true
    resolve_target_entities:
        AcmeFolderBundleEntityFolderInterface: AcmeNewBundleEntityFolder

如果我尝试更新数据库架构,则会收到以下错误:

[DoctrineDBALSchemaSchemaException]                                 
The table with name 'foldersDatabase.folder' already exists.

要使其正常工作,我必须显式更改文件夹的实体表之一:

namespace AcmeFolderBundleEntity;
/**
 * @ORMEntity
 * @ORMTable(name="distributed_folder")
 */
class Folder implements FolderInterface
{
    // Has many files
}

然后,一切正常,但我卡住了数据库中从未使用的表(distributed_folder)。

提前非常感谢!!

编辑:修复文件夹界面中的注释

您不能以这种方式使一个实体扩展另一个实体。如果你想要一个包含两个或多个子类实体的字段的抽象类,你应该将抽象类标记为@ORM\MappedSuperclass,并确保它不会有注释@Entity。在子类上,它们都应该有@Entity注解,并且@Table注解具有唯一的名称属性。

这是一个例子:

<?php
namespace RadsphereMissionBundleModelCoreBaseAbstract;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
/**
 * @ORMMappedSuperclass
 *
 * An abstract class implementation of mission
 */
 abstract class AbstractMission implements MissionInterface, IntegratedPluginInterface
 {
 /**
 * @ORMId()
 * @ORMColumn(name="id", type="integer")
 * @ORMGeneratedValue(strategy="AUTO")
 */
  protected $id;
/**
 * @ORMColumn(type="string", length=36, unique=true)
 */
protected $guid;
/**
 * @ORMColumn(type="string", length=255)
 */
protected $title;

/**
 * @ORMManyToMany(targetEntity="MissionTask", cascade={"persist", "remove"})
 * @ORMJoinTable(name="mtm_mission_task",
 *      joinColumns={@ORMJoinColumn(name="mission_id", referencedColumnName="id", onDelete="CASCADE")},
 *      inverseJoinColumns={@ORMJoinColumn(name="task_id", referencedColumnName="id", onDelete="CASCADE")}
 *      )
 */
protected $tasks;

/**
 * {@inheritDoc}
 */
public function addTask(MissionTaskInterface $missionTask)
{
    $this->getTasks()->add($missionTask);
    $missionTask->setMission($this);
}
/**
 * {@inheritDoc}
 */
public function setTasks(Collection $tasks)
{
    /** @var MissionTaskInterface $task */
    foreach ($tasks as $task) {
        $task->setMission($this);
    }
    $this->tasks = $tasks;
}
/**
 * {@inheritDoc}
 */
public function getTasks()
{
    $tasks = $this->tasks;
    foreach ($tasks as $task) {
        if ($task instanceof MissionTaskInterface) {
            if (!$task->getIsEnabled()) {
                /** @var $tasks Collection */
                $tasks->removeElement($task);
            }
        }
    }
    return $tasks;
}

}

和实体本身:

   <?php
   namespace RadsphereMissionBundleEntity;
   use DoctrineORMMapping as ORM;
   use DoctrineCommonCollectionsArrayCollection;
   use RadsphereMissionBundleModelCoreBaseAbstractAbstractMission;
   /**
   * Mission entity
   *
   * @ORMTable(name="mission_bundle_mission", indexes={@ORMIndex(name="guid_idx",      columns={"guid"})})
   * @ORMHasLifecycleCallbacks
   * @ORMEntity(repositoryClass="MissionRepository")
   */
   class Mission extends AbstractMission
   {
   /**
    * Constructor
   */
   public function __construct()
   {
      $this->tasks = new ArrayCollection();
   }
 }

最新更新