symfony 在persist上获取托管和脏实体错误

r9f1avp5  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(107)

我有以下代码:

$count = 0;
/** @var Order $order */
foreach ($orders as $order) {
    $output->write(sprintf('Processing order %s... ', ($count + 1), $order->getReference()));
    if ($this->shouldSkip($order)) {
        $output->writeln('Doesn\'t meet criteria, skipping.');
        continue;
    }
    $paymentPlanName = PayoutPlanFactory::make($order)->getPayoutPlanName();
    $output->write(sprintf('Setting payment plan to %s...', $paymentPlanName));
    $order->setPayoutPlan($paymentPlanName);
    $em->persist($order);
    $output->writeln(' Done.');

    if ((++$count % 1000) === 0) {
        $output->write('Flushing records... ');
        $em->flush();
        $output->writeln('Done.');
        $output->write('Clearing em... ');
        $em->clear();
        $output->writeln('Done.');
    }
}
$em->flush();
$em->clear();

当我运行这个命令时,输出结果与我期望的前1000条记录完全一致。我得到了订单参考,然后是它设置的支付计划。我也在DB中查找,我的记录在那里更新。但是,当它从第1001行开始时,我得到以下错误:

[Doctrine\ORM\ORMInvalidArgumentException]                                      
  A managed+dirty entity 57b6fed7b4ad7 can not be scheduled for insertion.

该ID与订单参考匹配。
我首先想到这可能是实体1001的问题,所以将批处理大小更改为50,然后它发生在它试图保存的第51个实体上。这几乎就像$em->clear();没有做它应该做的事情。
有什么方法可以解决这个问题吗?

zxlwwiss

zxlwwiss1#

如果您的订单来自使用存储库功能的数据库,首先清除分离它们.这就是为什么在第一批1000个之后,什么都不工作了。教条让人头脑发热。哈哈
但你离解决方案不远了。
在你的函数之上尝试类似这样的东西

$orders = $this->$orderRepository->findAll();
 $orderIds = array_map(function (Order $value) {
                return $value->getId();
 }, $orders);

 // this way you only iterate over an array of ids
 $this->em->clear() // detach all orders from entity manager : freeing memory
 $count = 0;
 foreach($orderIds => $orderId){
   
    $order = $this->$orderRepository->find($orderId);
    // your code here
 }

这样你也能实现你的目标:通过释放内存来保持对大记录的性能。
很高兴知道:->persist($object)仅对新实体有用。如果你的对象来自任何一个存储库函数,那么它已经被持久化了.
这个答案非常适合中型到大型数据集。由于->find(),您将拥有与记录数量相等的查询数量。这对于非常大量的数据来说可能是不好的。由于在良好和最新的数据库版本中通过id查询非常快,因此这可能就足够了。
但对于非常大和非常大的数据集。使用分批法的学说也很简单: www.example.com 或
www.example. com

相关问题