2016-07-30 5 views
1

구체적으로 말씀 드리겠습니다. 엔티티 퀘스트, 도시 및 조직자가 있습니다. 나 주최자 제거하려고하면 즉 갖는다 퀘스트 에러 관계는 'WHERE ID =? 주최자 삭제'symfony (교리)에서 엔티티의 관계에 대한 컨설팅

예외가 실행하는 동안 발생 나타나는 와 PARAMS [522] :

SQLSTATE [23000] : 무결성 제약 조건 위반 : 1451 삭제할 수 없습니다 또는 업데이트는 부모 행 :. 외래 키 제약 조건이 (실패 testQuest, CONSTRAINT FK_82D6D713876C4DDA FOREIGN KEY (organizer_id) 참조 Organizer (id))

나는 관계를 구성하는 올바른 방법과 절대 혼동합니다. 로직은 다음과 같습니다.

  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 가지를 잊어 버렸습니다.

  • PHP 빈/콘솔 교리

    1. 교리 생명주기 이벤트 : 생성 : 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와 함께 사용할 수있는 것처럼.

    추신 : 나는 이와 같은 과제를 해결하는 더 좋은 방법이 있음을 확신합니다. 그래서, 나는 너에게 비난의 마음을 열었다.

  • 2

    문제는 간단합니다. 기존 퀘스트에서 참조 했으므로 이끌이를 삭제할 수 없습니다. 귀하의 경우 먼저 관계를 제거해야합니다. 나는 doctrine을 사용하여 자동으로 수행하는 방법을 모르지만 preRemove 이벤트에서 이벤트 리스너를 구성하고 Quest Organizer 필드를 null로 만들 수 있습니다. 이벤트 리스너가 symfony 2.1에서 구현되었는지는 잘 모르겠지만 희망합니다. 또한 제거 호출 전에 컨트롤러에서 직접 관계 null을 수행 할 수 있습니다. 같은 경우가 도시에 적용됩니다. 이 문서화 링크를 확인하십시오 :

    How to Register Event Listeners and Subscribers

    Doctrine Lifecycle Events

    희망이 당신을 도와.

    1

    Doctrine 또는 DB를 구성하여 관계를 null로 설정해야합니다.교리와

    • , 너무 당신의 엔티티를 제거합니다

      $em=$this->getDoctrine()->getEntityManager(); // or getManager() in current Doctrine versions. 
      $em->remove($organizer); 
      $em->flush(); 
      
    • 당신의 DB로 : 당신이 것이 두 번째 방법을

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

      :

      이 JoinColumn 주석을 변경

      DQL 쿼리를 사용할 수 있어야합니다. 이 방법은 교리를 우회하며, 첫 번째가 좋습니다.

    +1

    그는 캐스케이드에서 퀘스트를 제거하고 싶지 않으며 관계 만 null로 만듭니다. 코드가 수행하는 작업인지 확인하십시오. – abdiel

    +0

    아, 이해가 안됐다. 나는 대답을 다시 썼다. 감사. – Alsatian

    관련 문제