Doctrine EntityManager clear method in nested enti

2019-04-09 10:20发布

I would like to use doctrine batch insert processing in order to optimize insert of a big amount of entities. The problem is with Clear method. It says that this method detach all entities that are managed by EntityManager. So what should I do in a situation where I have a parent Entity, which has many child, and each child has their childs, like this:

  • riseSession
    • track
      • points

So I have 1 rideSession, 3 tracks and each track has for isntance 2 000 points. I could use batch processing in last loop which is responsible for saving points. But if I use clear method, then how to set parents for points and tracks? Clear method will detach them, right?

2条回答
Anthone
2楼-- · 2019-04-09 11:06

Soon You will hit memory limit. The idea of flush() in batches is ok, but You need to clear() EntityManager at the end of each batch to release used memory.

But in Your case, You will have ORMInvalidArgumentException (a.k.a. "new entity foung through relationship") if You will call $child->setParent($parent); after You did $entityManager->clear();.

Problem is that $parent is now in detached state in UnitOfWork. So You need to put it again in managed state. This can be done by using $entityManager->merge(); or simply by using $parentRepository->find($parent->getId());.

Just make sure to bring up all Entities to managed state after each clear() in case You going to use them later.

查看更多
我想做一个坏孩纸
3楼-- · 2019-04-09 11:16

If you have all your 40000 objects already loaded in memory then you can just use code without clearing. Clearing on entity manager are used for optimising memory in PHP script. If you have enough memory to store all the objects you don't need to clear entity manager at all.

To optimise memory in that case you can unset($entity) after every persist.

And to fit DB connection bandwidth you can group several entities as in example.

$batchSize = 20;
for ($i = 1; $i <= 10000; ++$i) {
    $em->persist($entities[$i]);
    unset($entities[$i]);
    if (($i % $batchSize) === 0) {
        $em->flush();
    }
}
$em->flush(); //Persist objects that did not make up an entire batch
查看更多
登录 后发表回答