Doctrine orm 关于symfony实体关系的咨询(原则)

Doctrine orm 关于symfony实体关系的咨询(原则),doctrine-orm,doctrine,symfony,symfony-2.1,Doctrine Orm,Doctrine,Symfony,Symfony 2.1,我会详细说明的。 我有实体任务、城市和组织者。 当我试图删除“组织者”时,会出现与任务相关的错误 执行“从管理器中删除id”时发生异常 =?'带参数[522]: SQLSTATE[23000]:完整性约束冲突:1451无法删除或删除 更新父行:外键约束测试失败。任务, 约束FK \-U 82D6D713876C4DDA外键管理器\-U id 引用组织者id 我对配置关系的正确方式完全感到困惑。 逻辑是: 我们增加了新的城市。 我们添加了新的组织者,并将城市加入组织者。 我们创建了新的任务,然后将

我会详细说明的。 我有实体任务、城市和组织者。 当我试图删除“组织者”时,会出现与任务相关的错误

执行“从管理器中删除id”时发生异常 =?'带参数[522]:

SQLSTATE[23000]:完整性约束冲突:1451无法删除或删除 更新父行:外键约束测试失败。任务, 约束FK \-U 82D6D713876C4DDA外键管理器\-U id 引用组织者id

我对配置关系的正确方式完全感到困惑。 逻辑是:

我们增加了新的城市。 我们添加了新的组织者,并将城市加入组织者。 我们创建了新的任务,然后将城市和组织者放入其中。 如果我们删除组织者-任务中的组织者id必须为 removedquest不能被删除。 如果我们删除组织者,则必须删除城市中的组织者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();
        }
    }

问题很简单,您无法删除组织者,因为它被现有任务引用。在您的情况下,您必须首先删除关系。我不知道用条令自动执行的方法,但您可以在preRemove事件中配置事件侦听器,并将Quest organizer字段设置为null。我不确定事件侦听器是否在symfony 2.1中实现,但我希望。您还可以选择在remove调用之前直接在控制器中执行关系null。城市也是如此。检查此文档链接:


希望这对您有所帮助。

问题很简单,您无法删除组织者,因为它被现有任务引用。在您的情况下,您必须首先删除关系。我不知道用条令自动执行的方法,但您可以在preRemove事件中配置事件侦听器,并将Quest organizer字段设置为null。我不确定事件侦听器是否在symfony 2.1中实现,但我希望。您还可以选择在remove调用之前直接在控制器中执行关系null。城市也是如此。检查此文档链接:


希望这对您有所帮助。

您必须配置Doctrine或DB以将关系设置为null

使用条令,只需删除您的实体即可:

$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;    
}
使用第二种方法,您将能够使用DQL查询。 这种方法绕过了原则,首选第一种方法


您必须配置Doctrine或DB以将关系设置为null

使用条令,只需删除您的实体即可:

$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;    
}
使用第二种方法,您将能够使用DQL查询。 这种方法绕过了原则,首选第一种方法


我忘记了两件重要的事情

生命周期事件 php bin/控制台原则:生成:实体 AppBundle/Entity/Quest将只生成通用方法。有 无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,并将其与城市和组织者实体中的事件预移除一起使用


PS我有信心有更好的实践来解决这样的任务。所以,我愿意接受批评

我忘了两件重要的事

生命周期事件 php bin/控制台原则:生成:实体 AppBundle/Entity/Quest将只生成通用方法。有 无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,并将其与城市和组织者实体中的事件预移除一起使用


PS我有信心有更好的实践来解决这样的任务。所以,我愿意接受批评

他不想删除cascade上的任务,只想将关系设为null,你确定你的代码就是这么做的吗?哦,好吧,我不明白。我重写了答案。谢谢。他不想删除cascade上的任务,只想让关系为空,你确定你的代码就是这么做的吗?哦,好的,我不明白。我重写了答案。谢谢