具有非常大集合的 Doctrine ORM Form\Element\ObjectMultiCheckbox 的性能问题
Performance issue with Doctrine ORM Form\Element\ObjectMultiCheckbox with really large collection
我与拥有超过 12.000 个条目的实体(展会 <-> 酒店)存在多对多关系。当我在表单中使用 DoctrineModule\Form\Element\ObjectMultiCheckbox 时,应用程序内存不足。似乎 ObjectMultiCheckbox 加载了保存在数据库中的每个实体,即使 Fair 实体未分配给任何酒店(反之亦然)。
这是具有酒店关系的 Fair 实体:
/**
* @ORM\ManyToMany(targetEntity="Hotel", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="fair_core_has_hotel", joinColumns={@ORM\JoinColumn(name="fair_core_id", referencedColumnName="id")})
*/
private $hotel;
这里是 FairForm 中的 ObjectMultiCheckbox:
$this->add(array(
'name' => 'hotel',
'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
'options' => array(
'entity' => 'hotel',
'unchecked_value' => '',
'object_manager' => $em,
'target_class' => 'Customer\Entity\Hotel',
'label_generator' => function($targetEntity) {
return "".$targetEntity->getLabel();
},
'attributes' => array('required' => false),
),
));
已经尝试将获取模式更改为 EXTRA_LAZY,但没有任何区别。而且关系是单向的,Hotel 实体对 Fair 实体一无所知。
有什么解决办法吗?还是我做错了什么?
以下是我目前使用的模块:
我认为您误解了 ObjectMultiCheckbox
表单元素的工作原理。
在 the Doctrine2 form element documentation 你可以读到:
When the Form gets rendered the findAll
method of the ObjectRepository
will be executed by default.
在您的情况下,这意味着它将找到目标 class 'Customer\Entity\Hotel'
的所有实体,因此这意味着所有 12.000 条记录。
难怪内存有问题:)
我认为您必须重构这部分代码,使其仅适用于选定的酒店。
您可以在 Example 3: extended version 中阅读有关如何执行此操作的信息。他们在那里展示了一个示例,其中他们配置了一个 find_method
,它使用您存储库中的特定方法,您可以在其中限制结果。
我与拥有超过 12.000 个条目的实体(展会 <-> 酒店)存在多对多关系。当我在表单中使用 DoctrineModule\Form\Element\ObjectMultiCheckbox 时,应用程序内存不足。似乎 ObjectMultiCheckbox 加载了保存在数据库中的每个实体,即使 Fair 实体未分配给任何酒店(反之亦然)。
这是具有酒店关系的 Fair 实体:
/**
* @ORM\ManyToMany(targetEntity="Hotel", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="fair_core_has_hotel", joinColumns={@ORM\JoinColumn(name="fair_core_id", referencedColumnName="id")})
*/
private $hotel;
这里是 FairForm 中的 ObjectMultiCheckbox:
$this->add(array(
'name' => 'hotel',
'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
'options' => array(
'entity' => 'hotel',
'unchecked_value' => '',
'object_manager' => $em,
'target_class' => 'Customer\Entity\Hotel',
'label_generator' => function($targetEntity) {
return "".$targetEntity->getLabel();
},
'attributes' => array('required' => false),
),
));
已经尝试将获取模式更改为 EXTRA_LAZY,但没有任何区别。而且关系是单向的,Hotel 实体对 Fair 实体一无所知。
有什么解决办法吗?还是我做错了什么?
以下是我目前使用的模块:
我认为您误解了 ObjectMultiCheckbox
表单元素的工作原理。
在 the Doctrine2 form element documentation 你可以读到:
When the Form gets rendered the
findAll
method of theObjectRepository
will be executed by default.
在您的情况下,这意味着它将找到目标 class 'Customer\Entity\Hotel'
的所有实体,因此这意味着所有 12.000 条记录。
难怪内存有问题:)
我认为您必须重构这部分代码,使其仅适用于选定的酒店。
您可以在 Example 3: extended version 中阅读有关如何执行此操作的信息。他们在那里展示了一个示例,其中他们配置了一个 find_method
,它使用您存储库中的特定方法,您可以在其中限制结果。