Symfony Doctrine2 manyToMany relationship not removed - Specific to SQLite Symfony Doctrine2 manyToMany relationship not removed - Specific to SQLite symfony symfony

Symfony Doctrine2 manyToMany relationship not removed - Specific to SQLite


I think I found a better solution: you can set the PRAGMA within Doctrine configuration. Like:

doctrine:    dbal:        # configure these for your database server        driver: 'pdo_sqlite'        #server_version: '5.7'        #charset: utf8mb4        #default_table_options:            #charset: utf8mb4            #collate: utf8mb4_unicode_ci        url: '%env(resolve:DATABASE_URL)%'        options:            'PRAGMA foreign_keys': 'ON'

I just tried it on my Symfony 4 application, re-created the database and tested using DB Browser for SQLite and it works as I expected.

Hope this helps


I managed to fix the problem. Here's my solution working for SQLite conections.

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');    }}

Service declaration

  app.event_listener.request_listener:        class: AppBundle\EventListener\RequestListener        arguments:            - '@doctrine'        tags:            - { name: kernel.event_listener, event: kernel.request }


I think the problem is that you have your trait Taggable set as the owning side of the ManyToMany relationship but your are deleting the inverse side and expecting something to happen as a result. Doctrine will only check the owning side of the relationship in order to persist any changes. See here for docs on this.

You can solve by making the Taggable the inverse side of each of your relationships, or by manually telling doctrine to delete the owning side.

The first solution will probably not work for you since you won't (easily) specify multiple inverse sides. (Are you sure a trait is the right way to go for this??)

The second solution is easy. In your entities like Project for your deleteTag($tag) function, call a delete function on the owning side (e.g., deleteProject($project). You will have to create if one does not exist.

class Project{    use Taggable;    public function deleteTag($tag)    {        $this->tags->removeElement($tag);        // persist on the owning side        $tag->deleteProject($this);    }}

EDIT:

After seeing full code, it looks like you are deleting correctly. Now you need to tell doctrine to carry that through. See this post for full details, but basically you can change your trait to this:

trait Taggable{     /**      * @var ArrayCollection      *      * @ORM\ManyToMany(      *     targetEntity="AppBundle\Entity\Tag",       *     cascade={"persist"},      *     onDelete="CASCADE"      * ) */protected $tags;// ...}