Doctrine manyToMany return PersistentCollection 而不是 ArrayCollection

Doctrine manyToMany return PersistentCollection instead of ArrayCollection

我正在使用 Symfony 3.1 和 Doctrine 2.5。

我像往常一样设置了多对多关系:

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

并向我的实体添加方法

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

问题是,当我加载我的实体时,学说在 $this->placeServices 属性 中放置了一个 PersistentCollection。这听起来不是什么大问题,除了当我构建一个表单来连接这两个实体(一个简单的带有 symfony 表单类型的多个复选框)时,当 $form->handleRequest() 被触发时,Doctrine 尝试注入新数据在我的实体中,如果 get/add/remove 方法未使用 ArrayCollection.

则抛出错误

我可以强制我的 getter/add/remove 方法将 PersistentCollection 转换为 ArrayCollection(使用 unwrap 方法),但是所建立的关系不会持久化。

我找到了一个解决方法,如果我在关系上设置 fetch="EAGER" 属性 是用 ArrayCollection 初始化的,并且关系是坚持。但我不确定这是一个好的解决方案。

谢谢:)

只需使用 Doctrine\Common\Collections\Collection 接口而不是 ArrayCollectionArrayCollectionPersistentCollection 实现了这个接口。

Doctrine 使用 PersistentCollection 来延迟加载实体。你是对的,使用 EAGER 并不总是一个好的解决方案 - 它可能会导致性能问题。