Doctrine manyToMany返回PersistentCollection而不是ArrayCollection [英] Doctrine manyToMany return PersistentCollection instead of ArrayCollection

查看:181
本文介绍了Doctrine manyToMany返回PersistentCollection而不是ArrayCollection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与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
/ pre>

并向我的实体添加方法

  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 /删除将PersistentCollection转换为ArrayCollection(使用unwrap方法)的方法,但是所做的关系不会持久存在。



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



谢谢:)

解决方案>

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



Doctine使用 PersistentCollection 用于延迟加载实体。你是对的,使用EAGER并不总是很好的解决方案,你可以有性能问题。


I'm working with Symfony 3.1 and Doctrine 2.5.

I setup a manyToMany relationship as I always do :

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

And add methods to my Entity

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

The thing is, when I load my entity, doctrine put a PersistentCollection in the $this->placeServices property. This does not sound like a big problem, except that when I build a form to connect those two entities (a simple multiple checkboxes with symfony form type), when $form->handleRequest() is triggered, Doctrine try to inject the new data in my entity, and throw an error if get/add/remove method are not using ArrayCollection.

I can force my getter/add/remove methods to transforme the PersistentCollection to ArrayCollection (using unwrap method) but then the relations made are not persisted.

I've found a workaround, if I set fetch="EAGER" on the relation the property is initialized with ArrayCollection, and the relation are persisted. But i'm not sure it's a good solution.

Thanks :)

解决方案

Just use Doctrine\Common\Collections\Collection interface instead of ArrayCollection. ArrayCollection is just a implementaton of Collection, as PersistentCollection.

Doctine uses PersistentCollection for lazy loading entities. You are right, using EAGER is not always good solution, you can have perfomance issues.

这篇关于Doctrine manyToMany返回PersistentCollection而不是ArrayCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆