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 接口而不是 ArrayCollection。 ArrayCollection 和 PersistentCollection 实现了这个接口。
Doctrine 使用 PersistentCollection 来延迟加载实体。你是对的,使用 EAGER 并不总是一个好的解决方案 - 它可能会导致性能问题。
我正在使用 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 接口而不是 ArrayCollection。 ArrayCollection 和 PersistentCollection 实现了这个接口。
Doctrine 使用 PersistentCollection 来延迟加载实体。你是对的,使用 EAGER 并不总是一个好的解决方案 - 它可能会导致性能问题。