使用Symfony4 + Doctrine2的OutOfMemoryException多对多双向

时间:2018-04-04 19:42:25

标签: symfony doctrine-orm out-of-memory

我有两个实体, MapParking MapParkingType 。 MapParking(停车场)实体可以有多种类型,MapParkingType(批次类型)属于许多停车场。

我遇到的问题是,当我在连接表中深入到大约50个条目时,每当我尝试加载任何以任何方式使用MapParkingType实体的视图时,Symfony就会窒息。

错误是:

  

(1/1)OutOfMemoryException

     

错误:允许的内存大小为134217728字节耗尽(尝试过   分配23072768字节)

这是我的相关MapParking实体类代码:

class MapParking extends MapItem
{
...

/**
 * Many Parking lots have Many types.
 * @ORM\ManyToMany(targetEntity="App\Entity\Map\MapParkingType", inversedBy="parkingLots")
 * @ORM\JoinTable(name="mapparking_types",
 *      joinColumns={@ORM\JoinColumn(name="mapparking_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
 *      )
 * @ORM\OrderBy({"name" = "ASC"})
 * @Serializer\SerializedName("parkingTypes")
 */
private $parkingTypes;

public function __construct() {
    $this->parkingTypes = new ArrayCollection();
}
...

public function getParkingTypes()
{
    return $this->parkingTypes;
}

public function addParkingType(MapParkingType $parkingType)
{
    if ($this->parkingTypes->contains($parkingType)) {
        return;
    }
    $this->parkingTypes->add($parkingType);
    $parkingType->addParkingLot($this);
}

public function removeParkingType(MapParkingType $parkingType)
{
    if (!$this->parkingTypes->contains($parkingType)) {
        return;
    }
    $this->parkingTypes->removeElement($parkingType);
    $parkingType->removeParkingLot($this);
}
}

相关的MapParkingType实体类代码:

class MapParkingType
{
  ...

  /**
   * @ORM\ManyToMany(targetEntity="MapParking", mappedBy="parkingTypes")
   */
  private $parkingLots;

  ...

  public function addParkingLot(MapParking $parkingLot)
  {
      if ($this->parkingLots->contains($parkingLot)) {
          return;
      }
      $this->parkingLots->add($parkingLot);
      $parkingLot->addParkingType($this);
  }

  public function removeParkingLot(MapParking $parkingLot)
  {
      if (!$this->parkingLots->contains($parkingLot)) {
          return;
      }
      $this->parkingLots->removeElement($parkingLot);
      $parkingLot->removeParkingType($this);
  }

}

有趣的是,如果我摆脱了这种关系的双向性 - 也就是说,删除反面的$ parkingLots字段,问题就会消失。但是,我需要这是一种双向关系。

为了更好地衡量,以下是通过API方法获取MapParkingType实体的方法:

public function getMapparkingtypesAction()
{
 $parkingTypes = $this->getDoctrine()->getRepository(MapParkingType::class)->findAll();

 $serializer = $this->container->get('jms_serializer');
 $serialized = $serializer->serialize($parkingTypes, 'json');
 $response = new Response($serialized, 200, array('Content-Type' => 'application/json'));

 return $response;
}

2 个答案:

答案 0 :(得分:0)

我看到你有一个递归调用

方法addParkingType调用addParkingLot,反之亦然,这就是你内存不足的原因。

答案 1 :(得分:0)

答案实际上并没有与关系类型有关,而是与序列化程序有关。我不得不从序列化中排除MapParkingType的$ parkingLots字段。

// MapParkingType

/**
 * @ORM\ManyToMany(targetEntity="MapParking", mappedBy="parkingTypes")
 * @Serializer\Exclude
 */
private $parkingLots;

关于序列化关系的两面(使用jms序列化程序包)的东西会吸收所有系统的内存。