2013-12-23 21 views
0

我試圖將一個包中的實體與另一個包中的另一個綁定,以使第二個獨立於第一個,並且能夠重用它。Symfony2使用接口的關係導致重複的表

我正在關注this文檔和this StackOverflows答案。

在可重複使用的包我有一個文件夾,文件屬於文件夾,並且接口是這樣的:

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 

如果我嘗試更新我的數據庫模式,我得到以下內容NG錯誤:

[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

註釋你不能讓一個實體擴展另一個實體這樣。 如果你想有一個包含兩個或更多子類實體字段的抽象類,你應該將抽象類標記爲@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(); 
    } 
} 
+0

我不能使用@ORM \ MappedSuperclass因爲父類的Acme \ FolderBundle \實體\文件夾下有很多文件,這是不允許你的解決方案。此外,如果是這樣的話,我不會看到用界面定義關係的意義([docs](http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html))。在該教程中,該接口與Customer或BaseCustomer具有多對一的關係,然後兩者都是實體,因爲這些包可以由他們自己或與其他人一起使用(在最後的想法部分中陳述)。 – amcastror

+0

您可以在抽象類中使用關係,但引用本身將會是實體。 – shacharsol

+0

從你的代碼中,我明白MissionTask Entity將與Mission有多對一的關係(如果我錯了,請糾正我)。如果是這樣的話,bundle不會被分離,並且不能被輕易重用:如果在另一個項目中我想使用FolderBundle,我將不得不編輯Folder類Acme \ FolderBundle \ Entity \ Folder(在你的例子中爲MissionTask Entity) 。 – amcastror