Symfony + Doctrine onFlu sh - Как пропустить вставку и обновление сущностей - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть следующий вариант использования: я читаю несколько объектов (проектов), которые имеют коллекции (элементы).

Для достижения определенной c функциональности я изменяю сущности проекта и добавляю элементы в коллекцию элементов , но я не хочу, чтобы эти изменения были сохранены! .

Есть несколько других сущностей, и когда я сохраняю их, все изменения сохраняются (обновления проекта и вставки элементов).

Я пытался решить эту проблему с помощью события onFlu sh в doctrine, но это не всегда работает:

  • Я не знаю, как удалить сущность из обновления (я использую detach), но это устарело
  • , в некоторых случаях я получаю сообщения об ошибках, таких как:

    Новый объект был найден через связь 'App \ Entity \ Item # project ', который не был настроен для каскадного сохранения операций для объекта: Proxies__CG __ \ App \ Entity \ Project@00000 00042a2548f0000000067efb063. Чтобы решить эту проблему: либо явно вызовите EntityManager # persist () для этого неизвестного объекта, либо настройте каскад, сохраните эту связь в отображении, например, @ManyToOne (.., cascade = {"persist"}). Если вы не можете выяснить, какая сущность вызывает проблему, реализуйте 'App \ Entity \ Project #__ toString ()', чтобы получить подсказку.

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

В 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 }

Любой ввод приветствуется!

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Пытались ли вы пересчитать набор изменений ассоциаций после внесения ваших изменений?

Изменение примитивных полей или ассоциаций требует, чтобы вы явно инициировали повторное вычисление набора изменений затронутой сущности. Это можно сделать, позвонив по номеру

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

Это то, что do c явно просит вас сделать.

0 голосов
/ 05 февраля 2020

Я не на 100%, но я думаю, что вы можете использовать $entityManage->clear($project)

Это может заставить Doctrine «забыть» о вашей сущности, поэтому никакие изменения, сделанные в ней, не будут сохранены.

...