Избегайте извлечения всех сущностей во время обработки handleRequest в Symfony 4 - PullRequest
0 голосов
/ 15 января 2020

Я создал форму для редактирования только двух свойств объекта, у которого есть четыре, два из которых являются связями со многими другими объектами.

Я использую форму для изменения двух строковых данных.

Когда handleRequest запускается после отправки формы в моем контроллере, моя страница загружается медленно и занимает много памяти. После поиска это происходит из-за того, что handleRequest извлекает содержимое всех свойств измененного объекта для проверки.

Можно ли изменить определенные свойства объекта без того, чтобы handleRequest загрузил все данные сущности?

Позвольте мне привести пример моих файлов:

/**
 * @ORM\Entity(repositoryClass="App\Repository\TracteurRepository")
 */
class Tracteur
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=30)
     * @Assert\NotBlank()
     * @Assert\Length(max=30)
     * @Assert\Type("string")
     */
    private $nom;

    /**
     * @ORM\Column(type="string", length=10)
     * @Assert\NotBlank()
     * @Assert\Length(max=10)
     * @Assert\Type("string")
     */
    private $tag;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\AlerteTracteur", mappedBy="tracteur", orphanRemoval=true)
     */
    private $alertes;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Poslog", mappedBy="tracteur")
     */
    private $poslogs;

    public function __construct()
    {
        $this->alertes = new ArrayCollection();
        $this->poslogs = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getNom(): ?string
    {
        return $this->nom;
    }

    public function setNom(string $nom): self
    {
        $this->nom = $nom;

        return $this;
    }

    public function getTag(): ?string
    {
        return $this->tag;
    }

    public function setTag(?string $tag): self
    {
        $this->tag = $tag;

        return $this;
    }

    /**
     * @return Collection|AlerteTracteur[]
     */
    public function getAlertes(): Collection
    {
        return $this->alertes;
    }

    public function addAlerte(AlerteTracteur $alerte): self
    {
        if (!$this->alertes->contains($alerte)) {
            $this->alertes[] = $alerte;
            $alerte->setTracteur($this);
        }

        return $this;
    }

    public function removeAlerte(AlerteTracteur $alerte): self
    {
        if ($this->alertes->contains($alerte)) {
            $this->alertes->removeElement($alerte);
            // set the owning side to null (unless already changed)
            if ($alerte->getTracteur() === $this) {
                $alerte->setTracteur(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Poslog[]
     */
    public function getPoslogs(?RechercheInformations $recherche): Collection
    {
        $poslogs = $this->poslogs;

        if(!empty($recherche)){
            $criteria = Criteria::create()
                ->andWhere(Criteria::expr()->andX(
                    Criteria::expr()->lte('dateCreation', $recherche->getDateFin()),
                    Criteria::expr()->gte('dateCreation', $recherche->getDateDebut())
                ))
            ;

            $poslogs = $poslogs->matching($criteria);
        }

        return $poslogs;
    }

    public function addPoslog(Poslog $poslog): self
    {
        if (!$this->poslogs->contains($poslog)) {
            $this->poslogs[] = $poslog;
            $poslog->setTracteur($this);
        }

        return $this;
    }

    public function removePoslog(Poslog $poslog): self
    {
        if ($this->poslogs->contains($poslog)) {
            $this->poslogs->removeElement($poslog);
            // set the owning side to null (unless already changed)
            if ($poslog->getTracteur() === $this) {
                $poslog->setTracteur(null);
            }
        }

        return $this;
    }
}

Моя форма:

class TracteurType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nom', TextType::class, [
                "required" => true,
            ])
            ->add('tag', TextType::class, [
                "required" => true,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Tracteur::class,
        ]);
    }
}

Мой контроллер:

    /**
     * @Route("/parametrage/tracteur/{id}/editer", name="tracteur_edit", methods={"GET","POST"})
     */
    public function edit(Request $request, int $id): Response
    {
        $tracteur = $this->em->getRepository(Tracteur::class)->findTracteur($id);

        $form = $this->createForm(TracteurType::class, $tracteur);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->persist($tracteur);
            $this->em->flush();
        }

        return $this->render('tracteur/edit.html.twig', [
            'page' => 'tracteurs',
            'tracteur' => $tracteur,
            'form' => $form->createView(),
        ]);
    }

ОБНОВЛЕНИЕ:

Это обратный след запроса, который загружает отношение:

#   File/Call
1   Doctrine\DBAL\Logging\LoggerChain->startQuery (line 894)
2   Doctrine\DBAL\Connection->executeQuery (line 1818)
3   Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getOneToManyStatement (line 1758)
4   Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadOneToManyCollection (line 2932)
5   Doctrine\ORM\UnitOfWork->loadCollection (line 704)
6   Doctrine\ORM\PersistentCollection->doInitialize (line 213)
7   Doctrine\ORM\PersistentCollection->initialize (line 280)
8   Doctrine\Common\Collections\AbstractLazyCollection->getIterator (line 45)
9   Symfony\Component\Validator\Constraints\AllValidator->validate (line 731)
10  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (line 593)
11  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateGenericNode (line 507)
12  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (line 310)
13  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (line 135)
14  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (line 58)
15  Symfony\Component\Form\Extension\Validator\Constraints\FormValidator->validate (line 731)
16  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (line 485)
17  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (line 310)
18  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (line 135)
19  Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (line 93)
20  Symfony\Component\Validator\Validator\RecursiveValidator->validate (line 66)
21  Symfony\Component\Validator\Validator\TraceableValidator->validate (line 50)
22  Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener->validateForm (line 230)
23  Symfony\Component\EventDispatcher\EventDispatcher->callListeners (line 59)
24  Symfony\Component\EventDispatcher\EventDispatcher->dispatch (line 33)
25  Symfony\Component\EventDispatcher\ImmutableEventDispatcher->dispatch (line 670)
26  Symfony\Component\Form\Form->submit (line 109)
27  Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest (line 492)
28  Symfony\Component\Form\Form->handleRequest (line 133)
29  App\Controller\TracteurController->edit (line 145)
30  Symfony\Component\HttpKernel\HttpKernel->handleRaw (line 67)
31  Symfony\Component\HttpKernel\HttpKernel->handle (line 191)
32  Symfony\Component\HttpKernel\Kernel->handle (line 27)
enter code here

1 Ответ

0 голосов
/ 15 января 2020

Помещение doctrine fetch = "EXTRA_LAZY" или fetch = "LAZY" при отображении должно помочь

...