2016-07-30 10 views
1

私は具体的になるでしょう。 私はエンティティクエスト、都市と主催者を持っています。クエストエラーと関係を持っている 私は主催者を削除しようと、実行中symfony(教義)のエンティティの関係についての相談

例外が発生した表示されます「= ID 主催。DELETE FROM?」

SQLSTATE [23000]:整合性制約違反:1451は、親行を削除するか 更新することはできません:paramsは[522]と外部キー制約が失敗(testQuest、 CONSTRAINT FK_82D6D713876C4DDA FOREIGN KEY(organizer_id) REFERENCES Organizerid))

私は、関係を構成する正しい方法と絶対に混同しています。 論理は:

  1. 新しい都市を追加します。
  2. 新しい主催者を追加し、主催者に都合を入れます。
  3. 新しいクエストを作成し、それに都市や主催者を入れるよりも、
  4. オーガナイザーを削除した場合 - オーガナイザーのIDは でなければなりません(クエストは削除しないでください)。
  5. オーガナイザーを削除して、都市のオーガナイザーIDを削除する必要がある場合は、 も削除する必要があります(都市を削除しないでください)。

私の非常に愚かな記述には申し訳ありませんが、私は誤解を排除しようとしています。

私の状況では、右エンティティの関係は何ですか?

class Quest { 
    ... 
    /** 
    * @ORM\JoinColumn(name="organizer_id", referencedColumnName="id") 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Organizer") 
    */ 
    protected $organizer;  
} 

class Organizer { 
    ... 
    /** 
    * @ORM\Column(type="string", length=140) 
    */ 
    protected $name; 

    /** 
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\City", inversedBy="organizers") 
    * @ORM\JoinTable(name="organizers_cities") 
    */ 
    protected $cities; 

    public function __construct() { 
     $this->quests = new ArrayCollection(); // i don't remember why this is here 
    } 
} 

class City { 

     /** 
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Organizer", mappedBy="cities") 
     */ 
     protected $organizers; 
     /** 
     * Constructor 
     */ 
     public function __construct() { 
      $this->quests = new \Doctrine\Common\Collections\ArrayCollection(); 
      $this->organizers = new \Doctrine\Common\Collections\ArrayCollection(); 
     } 
    } 

答えて

1

私は2つの重要なことを忘れました。

  1. 教義のライフサイクルイベント
  2. PHPのbin /コンソール教義:生成:エンティティ AppBundle /エンティティ/クエストが唯一の共通のメソッドを生成します。 ( removeOrganizer()関数がありませんでした)

解決方法は簡単ですが、以下を参照してください。

class Quest { 
    ... 
    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Organizer", inversedBy="quests") 
    * @ORM\JoinColumn(name="organizer_id", referencedColumnName="id") 
    */ 
    protected $organizer; 

    ... 
    public function removeOrganizer() 
    { 
     $this->organizer = null; 
     return $this; 
    } 
    public function removeCity() 
    { 
     $this->city = null; 
     return $this; 
    } 
} 
class Organizer { 
    ... 
    /** 
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\City", inversedBy="organizers") 
    */ 
    protected $cities; 
    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\Quest", mappedBy="organizer")) 
    */ 
    protected $quests; 

    public function __construct() { 
     $this->quests = new ArrayCollection(); 
    } 
    ... 
    /** 
    * @ORM\PreRemove() 
    */ 
    public function removeRelationWithQuests() { 
     foreach($this->getQuests() as $quest) { 
      $quest->removeOrganizer() 
        ->setStatus(0); 
     } 
    } 
} 
class City { 
    ... 
    /** 
    * @OneToMany(targetEntity="AppBundle\Entity\Quest", mappedBy="city")) 
    */ 
    protected $quests; 
    /** 
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Organizer", mappedBy="cities") 
    */ 
    protected $organizers; 
    ... 
    /** 
    * @ORM\PreRemove() 
    */ 
    public function removeRelationWithQuests() { 
     foreach($this->getQuests() as $quest) { 
      $quest->removeCity() 
        ->setStatus(0); 
     } 
    } 
} 

あなたは私がクエストエンティティのための新機能removeOrganizerとremoveCityを追加参照し、市のイベントは、preremoveと主催エンティティでそれを使用することができたよう。

PS私は、このようなタスクを解決する方が良いという確信があります。だから、私はあなたのために批判のために開いています。

2

問題は簡単ですが、既存のクエストで参照されているため、主催者を削除することはできません。あなたの場合、最初に関係を削除する必要があります。 doctrineで自動的に行う方法はわかりませんが、preRemoveイベントでイベントリスナーを設定し、Questオーガナイザフィールドをnullにすることができます。イベントリスナーがsymfony 2.1に実装されているかどうかはわかりませんが、私は願っています。また、removeコールの前に、コントローラで直接関係nullを実行するオプションもあります。同じケースが都市に適用されます。このドキュメンテーションリンクチェック:

How to Register Event Listeners and Subscribers

Doctrine Lifecycle Events

希望をこのヘルプます。

1

DoctrineまたはDBを設定して、リレーションをnullに設定する必要があります。教義と

  • 、ちょうどので、あなたのエンティティを削除:あなたのDBと

    $em=$this->getDoctrine()->getEntityManager(); // or getManager() in current Doctrine versions. 
    $em->remove($organizer); 
    $em->flush(); 
    
  • を:あなたは意志この第二の方法では

    class Quest { 
        ... 
        /** 
        * @ORM\JoinColumn(nullable=false, onDelete="SET NULL",name="organizer_id", referencedColumnName="id") 
        * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Organizer") 
        */ 
        protected $organizer;  
    } 
    

    あなたのJoinColumnアノテーションを変更

    DQLクエリを使用できるようにします。 このメソッドはdoctrineをバイパスし、最初のメソッドが優先されます。

+1

カスケードでクエストを削除したくない場合は、関係をnullにするだけです。コードが実行していることを確認してください。 – abdiel

+0

ああ、okは理解していない。私は答えを書き換えた。ありがとう。 – Alsatian

関連する問題