Doctrine manyToMany返回PersistentCollection而不是ArrayCollection

时间:2016-07-16 11:21:32

标签: php symfony doctrine-orm php-7

我正在使用Symfony 3.1和Doctrine 2.5。

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

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

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

我可以强制我的getter / add / remove方法将PersistentCollection转换为ArrayCollection(使用unwrap方法)但是后续关系不会被保留。

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

谢谢:)

1 个答案:

答案 0 :(得分:32)

只需使用 Doctrine \ Common \ Collections \ Collection 界面,而不是 ArrayCollection ArrayCollection PersistentCollection 实现此界面。

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

相关问题