Как обновить загрузку объекта с помощью ServiceEntityRepository - PullRequest
0 голосов
/ 05 июля 2019

Я загрузил сущность, используя Doctrine \ Bundle \ DoctrineBundle \ Repository \ ServiceEntityRepository (новая рекомендация в SF4), и я хочу обновить эту сущность.

Но $entityManager->clear() не выполняет эту работу и

$entityManager->refresh($myentity) 

сказал мне

Doctrine \ ORM \ ORMInvalidArgumentException: Entity App \ Entity \ MyEntity @ 0000000068ed8bf0000000007dca9dd1 не удалось.Объект управляется, если он извлечен из базы данных или зарегистрирован как новый через EntityManager # persist

Вот мой репо:

    <?php

    namespace App\Core\Repository;

    use App\Core\Entity\Question;
    use App\Core\Entity\QuestionnaireResponse;
    use App\Core\Entity\Reponse;
    use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
    use Symfony\Bridge\Doctrine\RegistryInterface;

    /**
     * @method Reponse|null find($id, $lockMode = null, $lockVersion = null)
     * @method Reponse|null findOneBy(array $criteria, array $orderBy = null)
     * @method Reponse[]    findAll()
     * @method Reponse[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
     */
    class ReponseRepository extends ServiceEntityRepository
    {
        /**
         * ReponseRepository constructor.
         * @param RegistryInterface $registry
         */
        public function __construct(RegistryInterface $registry)
        {
            parent::__construct($registry, Reponse::class);
        }

    }

Вот мой testSetup:

<?php

/* 
 *   Created by Aurelien Jolivard on 24/01/2019.
 */

namespace App\Core\Service;

use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManager;
use Symfony\Bridge\Doctrine\ContainerAwareEventManager;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;


class TestSetUp extends WebTestCase
{
    /** @var EntityManager $em */
    protected $em;
    protected $application;

    public function beginningTest(String $fixtures){

        static::$kernel = static::createKernel(array(
            'environment' => 'test',
            'debug'       => 'true'
        ));
        static::$kernel->boot();

        $application = new Application(static::$kernel);

        // get the Entity Manager
        /** @var EntityManager $em */
        $em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager();

        /** @var ContainerAwareEventManager $evm */
        $evm = $em->getEventManager();

        // drop the database
        $command = new DropDatabaseDoctrineCommand(static::$kernel->getContainer()->get('doctrine'));
        $application->add($command);
        $input = new ArrayInput(array(
            'command' => 'doctrine:database:drop',
            '--force' => true,
            '--env' => 'test'
        ));
        $command->run($input, new NullOutput());

        // we have to close the connection after dropping the database so we don't get "No database selected" error
        $connection = $application->getKernel()->getContainer()->get('doctrine')->getConnection();
        if ($connection->isConnected()) {
            $connection->close();
        }

        // create the database
        $command = new CreateDatabaseDoctrineCommand(static::$kernel->getContainer()->get('doctrine'));
        $application->add($command);
        $input = new ArrayInput(array(
            'command' => 'doctrine:database:create',
            '--env' => 'test'
        ));
        $command->run($input, new NullOutput());

        // create schema
        $command = new CreateSchemaDoctrineCommand();
        $application->add($command);
        $input = new ArrayInput(array(
            'command' => 'doctrine:schema:create',
            '--env' => 'test'
        ));
        $command->run($input, new NullOutput());

        // load fixtures
        $client = static::createClient();
        $loader = new ContainerAwareLoader($client->getContainer());
        $loader->loadFromFile(static::$kernel->getProjectDir().$fixtures);
        $purger = new ORMPurger($em);
        $executor = new ORMExecutor($em, $purger);
        $executor->execute($loader->getFixtures());

        $this->em = $em;
        $this->application = $application;
        return ;

    }
}

А вот мой тест, в котором я пытаюсь очистить данные.

<?php

namespace App\Core\Tests\Form\FunctionalTest;


use App\Core\Entity\Questionnaire;
use App\Core\Entity\QuestionnaireResponse;
use App\Core\Entity\Reponse;
use App\Core\Service\TestSetUp;
use Doctrine\ORM\EntityManager;


class QuestionTypeBooleanTest extends TestSetUp
{
    public function setUp()
    {
        $array = $this->beginningTest('/src/Core/DataFixtures/AppFixturesQuestionTypeBoolean.php');
        //$this->em = $array[0];
        //$this->application = $array[1];
    }

    /**
    * @group question
    * @group test_BrouillonPuisSoumission
    */
    public function test_BrouillonPuisSoumission()
    {

        // vérification de l'état de la base de données avant

        $client = static::createClient(
            array('environment' => 'test') ,   
        );

        $questionnaire =  $this->em->getRepository(Questionnaire::class)->findSystemAndValue('system', '123');

        $crawler = $client->request(
            'GET',   
            '/questionnaire/'.$questionnaire->getId().'/display/1'
        );
        $response = $client->getResponse();
        $this->assertEquals(200, $response->getStatusCode());

        $form = $crawler->selectButton('appbundle_questionnaire_display[draft]')->form();
        $form['appbundle_questionnaire_display[1]'] = 0;
        $form['appbundle_questionnaire_display[2]'] = 1;
        $crawler = $client->submit($form);

        $response = $client->getResponse();

        $this->assertEquals(302, $response->getStatusCode());

        // vérification de l'état de la base de données
        $reponse1 = $this->em->getRepository(Reponse::class)->find(1);
        $reponse2 = $this->em->getRepository(Reponse::class)->find(2);
        $questionnaireResponse = $this->em->getRepository(QuestionnaireResponse::class)->find(1);
        $this->assertEquals('0', $reponse1->getValeur(), 'cas1.1');
        $this->assertEquals('1', $reponse2->getValeur(), 'cas1.2');
        $this->assertEquals(2, $questionnaireResponse->getVersionId());

        $crawler = $client->request(
            'GET',   
            '/soumission/1/edit'
        );
        $response = $client->getResponse();

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertEquals(0, $crawler->filter('form[name="appbundle_questionnaire_display"]')->form()->getValues()['appbundle_questionnaire_display[1]'], 'cas2.1');
        $this->assertEquals(1, $crawler->filter('form[name="appbundle_questionnaire_display"]')->form()->getValues()['appbundle_questionnaire_display[2]'], 'cas2.2');

        $form = $crawler->selectButton('appbundle_questionnaire_display[submit]')->form();
        $form['appbundle_questionnaire_display[1]'] = 1;
        $form['appbundle_questionnaire_display[2]'] = 0;

        $crawler = $client->submit($form);

        $response = $client->getResponse();
        $this->assertEquals(302, $response->getStatusCode());

        $this->em->refresh($reponse1);
        $this->em->refresh($reponse2);
        $this->em->refresh($questionnaireResponse);
        //$this->em->clear();

        $this->assertEquals('1', $this->em->getRepository(Reponse::class)->find(1)->getValeur(), 'cas3.1');
        $this->assertEquals('0', $this->em->getRepository(Reponse::class)->find(2)->getValeur(), 'cas3.2');
        $this->assertEquals(3, $this->em->getRepository(QuestionnaireResponse::class)->find(1)->getVersionId());
    }
}

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

Я нашел решение.

EntityManager, который я получаю в TestSetUp, не тот, который используется ServiceEntityRepository. Это связано с конструкцией ServiceEntityRepository.

Si, чтобы очистить хороший EntityManager, я должен вызвать очистку в репозитории, а не в EntityManger:

public function test_BrouillonPuisSoumission()
    {

        // ...

        // vérification de l'état de la base de données
        $reponseRepository =  $this->em->getRepository(Reponse::class);
        $questionnaireResponseRepository = $this->em->getRepository(QuestionnaireResponse::class);
$this->em->getRepository(QuestionnaireResponse::class)->find(1)->getVersionId());
        $this->assertEquals('0', $reponseRepository->find(1)->getValeur(), 'cas1.1');
        $this->assertEquals('1', $reponseRepository->find(2)->getValeur(), 'cas1.2');
        $this->assertEquals(2, $questionnaireResponseRepository->find(1)->getVersionId());


        // ...

        $reponseRepository->clear();
        $questionnaireResponseRepository->clear();

        $this->assertEquals('1', $reponseRepository->find(1)->getValeur(), 'cas3.1');
        $this->assertEquals('0', $reponseRepository->find(2)->getValeur(), 'cas3.2');
        $this->assertEquals(3, $questionnaireResponseRepository->find(1)->getVersionId());
    }
0 голосов
/ 06 июля 2019

Doctrine / ORM / EntityManager :: clear () метод

Очищает EntityManager.Все сущности, которые в данный момент управляются этим EntityManager, становятся отсоединенными.

Doctrine / ORM / EntityManager :: refresh () method

Обновляет постоянное состояние объекта из базы данных, переопределяя все локальные изменения, которые еще не были сохранены.

Чтобы обновить объект, просто выполните:

$entityManager->refresh($myentity)

без clear () перед ним, удалите его.

...