2
votes

I have the following use-case: I read multiple entities(Projects) which have collections(Items).

In order to achieve a specific functionality, I do change the Project entities and add stuff to the items collection, but I don't want these changes to be saved!.

There are several other entities involved and when I save those, all changes gets saved(project updates and item inserts).

I tried to solve this with the onFlush event in doctrine, but it doesn't always work:

  • I don't know how to remove an entity from the update (I use detach) but that is deprecated
  • in some cases I get errors like:

    A new entity was found through the relationship 'App\Entity\Item#project' that was not configured to cascade persist operations for entity: Proxies__CG__\App\Entity\Project@00000 00042a2548f0000000067efb063. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mappin g for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Entity\Project#__toString()' to get a clue.

App\EventListener\DoctrineFlushListener.php

namespace App\EventListener;

use Doctrine\ORM\Event\OnFlushEventArgs;

class DoctrineFlushListener
{
    /**
     * @param OnFlushEventArgs  $args
     */
    public function onFlush(OnFlushEventArgs  $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if (method_exists($entity, 'isOrmSkipInsert')) {
                if ($entity->isOrmSkipInsert()) {
                    $uow->remove($entity);
                }
            }
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if (method_exists($entity, 'isOrmSkipSave')) {
                if ($entity->isOrmSkipSave()) {
//                    $uow->refresh($entity);
                    //$uow->markReadOnly($entity);
//                    $uow->detach($entity);
                }
            }
        }
    }
}

In services.yaml

    app.doctrine.flush:
        class: App\EventListener\DoctrineFlushListener
        tags:
            - { name: doctrine.event_listener, event: onFlush }
#            - { name: doctrine.event_listener, event: preFlush }
#            - { name: doctrine.event_listener, event: prePersist }

Any input is welcomed!

2

2 Answers

0
votes

I'm not 100% but I think you can use $entityManage->clear($project)

It will mage Doctrine to "forget" about your entity, so no changes made to it will be saved.

0
votes

Have you tried to recompute the associations changeset after you did your changes?

Changing primitive fields or associations requires you to explicitly trigger a re-computation of the changeset of the affected entity. This can be done by calling

$uow->recomputeSingleEntityChangeSet($classMetadata, $entity);

This is what the doc explicitly asks you to do.