我会具体。 我有实体任务,城市和组织者。 当我尝试删除组织者时,会出现与任务错误的关系
执行'DELETE FROM Organizer WHERE id时发生异常 =?'与params [522]:
SQLSTATE [23000]:完整性约束违规:1451无法删除或 更新父行:外键约束失败(
test
。Quest
, 约束FK_82D6D713876C4DDA
外键(organizer_id
) 参考Organizer
(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();
}
}
答案 0 :(得分:2)
问题很简单,您无法删除组织者,因为现有的Quest会引用它。在您的情况下,您必须首先删除关系。我不知道使用doctrine自动执行此操作的方法,但您可以在preRemove事件中配置事件侦听器,并使Quest管理器字段为null。我不确定事件监听器是否在symfony 2.1中实现,但我希望如此。您还可以选择在删除调用之前直接在控制器中执行关系null。同样的情况适用于城市。查看此文档链接:
How to Register Event Listeners and Subscribers
希望这对你有所帮助。
答案 1 :(得分:1)
您必须配置Doctrine或DB以将关系设置为null。
使用doctrine,只需删除您的实体:
$em=$this->getDoctrine()->getEntityManager(); // or getManager() in current Doctrine versions.
$em->remove($organizer);
$em->flush();
使用您的数据库:
更改JoinColumn注释:
class Quest {
...
/**
* @ORM\JoinColumn(nullable=false, onDelete="SET NULL",name="organizer_id", referencedColumnName="id")
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Organizer")
*/
protected $organizer;
}
使用第二种方法,您将能够使用DQL查询。 这种方法绕过了学说,第一种是首选。
答案 2 :(得分:1)
我忘记了两件重要的事情。
所以,解决方案很简单,但是......见下文。
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);
}
}
}
如您所见,我为Quest Entity添加了新功能removeOrganizer和removeCity,并将其与City and Organizer Entity中的事件preRemove一起使用。
PS我相信有更好的解决这样的任务的做法。所以,我愿意批评你。