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

时间:2013-12-23 22:21:35

标签: symfony inheritance doctrine-orm

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

我正在关注this文档和this StackOverflows回答。

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

namespace Acme\FolderBundle\Entity;
/**
 * @ORM\Entity
 */
class Folder implements FolderInterface
{
    // Has many files
}

namespace Acme\FolderBundle\Entity;

interface FolderInterface
{
    // no methods here
}

namespace Acme\FolderBundle\Entity;
/**
 * @ORM\Entity
 */
class File
{
    // Belongs to one folder
}

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

namespace Acme\NewBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Acme\FolderBundle\Entity\Folder as BaseFolder;
use Acme\FolderBundle\Entity\FolderInterface;

/**
 * @ORM\Entity
 */
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:
        Acme\FolderBundle\Entity\FolderInterface: Acme\NewBundle\Entity\Folder

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

[Doctrine\DBAL\Schema\SchemaException]                                 
The table with name 'foldersDatabase.folder' already exists.

要实现这一点,我必须明确更改其中一个文件夹的实体表:

namespace Acme\FolderBundle\Entity;
/**
 * @ORM\Entity
 * @ORM\Table(name="distributed_folder")
 */
class Folder implements FolderInterface
{
    // Has many files
}

然后,一切正常但我在数据库(distributed_folder)中遇到了一个从未使用过的表。

提前多多感谢!!

编辑: 修复了FolderInterface

中的注释

1 个答案:

答案 0 :(得分:1)

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

以下是一个例子:

<?php

namespace Radsphere\MissionBundle\Model\Core\BaseAbstract;

use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass
 *
 * An abstract class implementation of mission
 */
 abstract class AbstractMission implements MissionInterface, IntegratedPluginInterface
 {
 /**
 * @ORM\Id()
 * @ORM\Column(name="id", type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
  protected $id;

/**
 * @ORM\Column(type="string", length=36, unique=true)
 */
protected $guid;

/**
 * @ORM\Column(type="string", length=255)
 */
protected $title;


/**
 * @ORM\ManyToMany(targetEntity="MissionTask", cascade={"persist", "remove"})
 * @ORM\JoinTable(name="mtm_mission_task",
 *      joinColumns={@ORM\JoinColumn(name="mission_id", referencedColumnName="id", onDelete="CASCADE")},
 *      inverseJoinColumns={@ORM\JoinColumn(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 Radsphere\MissionBundle\Entity;

   use Doctrine\ORM\Mapping as ORM;
   use Doctrine\Common\Collections\ArrayCollection;
   use Radsphere\MissionBundle\Model\Core\BaseAbstract\AbstractMission;

   /**
   * Mission entity
   *
   * @ORM\Table(name="mission_bundle_mission", indexes={@ORM\Index(name="guid_idx",      columns={"guid"})})
   * @ORM\HasLifecycleCallbacks
   * @ORM\Entity(repositoryClass="MissionRepository")
   */
   class Mission extends AbstractMission
   {
   /**
    * Constructor
   */
   public function __construct()
   {

      $this->tasks = new ArrayCollection();
   }
 }