web-dev-qa-db-fra.com

Doctrine manyToMany renvoie PersistentCollection au lieu de ArrayCollection

Je travaille avec Symfony 3.1 et Doctrine 2.5.

J'établis une relation manyToMany comme je le fais toujours:

manyToMany:
        placeServices:
            targetEntity: Acme\MyBundle\Entity\PlaceService
            joinTable:
                name: place_place_service
                joinColumns:
                    place_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    place_service_id:
                        referencedColumnName: id

Et ajouter des méthodes à mon entité

    protected $placeServices;

    ...

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

    ...

    /**
     * @return ArrayCollection
     */
    public function getPlaceServices(): ArrayCollection
    {
        return $this->placeServices;
    }

    /**
     * @param PlaceServiceInterface $placeService
     * @return PlaceInterface
     */
    public function addPlaceService(PlaceServiceInterface $placeService): PlaceInterface
    {
        if(!$this->placeServices->contains($placeService)) {
            $this->placeServices->add($placeService);
        }

        return $this;
    }

    /**
     * @param PlaceServiceInterface $placeService
     * @return PlaceInterface
     */
    public function removePlaceService(PlaceServiceInterface $placeService): PlaceInterface
    {
        if($this->placeServices->contains($placeService)) {
            $this->placeServices->removeElement($placeService);
        }

        return $this;
    }

Le problème est que lorsque je charge mon entité, doctrine place un PersistentCollection dans la propriété $ this-> placeServices. Cela ne ressemble pas à un gros problème, sauf que lorsque je crée un formulaire pour connecter ces deux entités (une simple case à cocher multiple avec le type de formulaire symfony), lorsque $ form-> handleRequest () est déclenché, Doctrine essayez d'injecter les nouvelles données dans mon entité et renvoie une erreur si la méthode get/add/remove n'utilise pas ArrayCollection.

Je peux forcer mes méthodes getter/add/remove à transformer la PersistentCollection en ArrayCollection (en utilisant la méthode unwrap) mais les relations établies ne sont pas persistées.

J'ai trouvé une solution de contournement, si j'ai défini fetch = "EAGER" sur la relation, la propriété est initialisée avec ArrayCollection et la relation est persistante. Mais je ne suis pas sûr que ce soit une bonne solution.

Merci :)

17
Thomas Piard

Utilisez simplement Doctrine\Common\Collections\Collection interface au lieu de ArrayCollection. ArrayCollection et PersistentCollection implémentent cette interface.

La doctrine utilise PersistentCollection pour les entités de chargement paresseux. Vous avez raison, utiliser EAGER n'est pas toujours une bonne solution - cela peut entraîner des problèmes de performances.

35
Artur Vesker