Symfony Doctrine2 manyToMany关系不删除 - 特定于SQLite [英] Symfony Doctrine2 manyToMany relationship not removed - Specific to SQLite
问题描述
我有几个类使用Taggable特征来建立一些标准系统,这些标签系统与几个教义实体(Project,Note,...)共同。
I have several classes using a Taggable trait to set up a tag system common to several doctrine entities (Project, Note, ...).
这些实体和这些标签是一个ManyToMany关系,我无法进行多方向。
The relationship between these entities and these tags is a ManyToMany relationship that I can not make multi-directional.
我的问题:当我删除一个项目实体时,它从项目表,但此项目与标记之间的 project_tag 表之间的关系不会被删除。然后,如果我创建一个新的项目实体,将抛出异常。
My problem: When I delete a Project entity, it is removed from the project table, but the relationships in the project_tag table between this project and the tags are not deleted. Then, if I create a new Project entity, an exception is thrown.
An exception exists while executing 'INSERT INTO project_tag (project_id, tag_id) VALUES (?,?)' With params [2, 4]:
SQLSTATE [23000]: Integrity constraint violation: 19 UNIQUE constraint failed: project_tag.project_id, project_tag.tag_id
实体:
标签
/**
* Tag
*
* @ORM\Table(name="tag")
* @ORM\Entity(repositoryClass="AppBundle\Repository\TagRepository")
*/
class Tag
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/**
* @ORM\Column(name="last_use_at", type="datetime", nullable=false)
* @var \DateTime
*/
private $lastUseAt;
public function __construct()
{
$this->lastUseAt = new \DateTime();
}
public function __toString()
{
return $this->name;
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Tag
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return \DateTime
*/
public function getLastUseAt(): \DateTime
{
return $this->lastUseAt;
}
/**
* @param \DateTime $lastUseAt
*/
public function setLastUseAt(\DateTime $lastUseAt)
{
$this->lastUseAt = $lastUseAt;
}
}
可标注
trait Taggable
{
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Tag", cascade={"persist"})
*/
protected $tags;
/**
* Add tag
*
* @param Tag $tag
*
* @return $this
*/
public function addTag(Tag $tag)
{
$tag->setLastUseAt(new \DateTime());
$this->tags[] = $tag;
return $this;
}
/**
* Remove tag
*
* @param Tag $tag
*/
public function removeTag(Tag $tag)
{
$this->tags->removeElement($tag);
}
/**
* Get tags
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
项目
/**
* Project
*
* @ORM\Table(name="project")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ProjectRepository")
*/
class Project
{
use Taggable;
}
笔记
class Note
{
use Taggable;
}
这是唯一的解决方案还是我的注释不完整/不正确?
我尝试使用JoinColumns,JoinTable和onDelete =cascade,但没有任何作用。
Is this the only solution or is my annotation incomplete / incorrect? I tried with JoinColumns, JoinTable and onDelete = "cascade" but nothing works.
在此期间,我躲避了在禁令之前的这个指令的问题。
In the meantime, I dodged the problem with this instruction placed before the suppresion.
$project->getTags()->clear ();
控制器中的操作的完整代码:
Full code of the action in the controller :
/**
* @Route("/project/{id}/delete", name="project_delete")
*/
public function deleteAction($id) {
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('AppBundle:Project')->find($id);
if(!$project) {
return $this->redirectToRoute('index');
}
$project->getTags()->clear();
$em->remove($project);
$em->flush();
return $this->redirectToRoute('index');
}
推荐答案
我设法解决了问题。这是我为SQLite连接工作的解决方案。
I managed to fix the problem. Here's my solution working for SQLite conections.
创建一个监听kernel.request事件的eventListener:
Create an eventListener listening on the kernel.request event :
namespace AppBundle\EventListener;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class RequestListener
{
/**
* @var Registry
*/
private $doctrine;
public function __construct(Registry $doctrine)
{
$this->doctrine = $doctrine;
}
public function onKernelRequest(GetResponseEvent $event)
{
$this->doctrine->getConnection()->exec('PRAGMA foreign_keys = ON');
}
}
服务声明
app.event_listener.request_listener:
class: AppBundle\EventListener\RequestListener
arguments:
- '@doctrine'
tags:
- { name: kernel.event_listener, event: kernel.request }
这篇关于Symfony Doctrine2 manyToMany关系不删除 - 特定于SQLite的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!