问题描述
我正在与Symfony 3.1和Doctrine 2.5一起工作。我像往常一样设置一个manyToMany关系:
manyToMany:
/ pre>
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 /删除将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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-05 06:21