如何让EntityManager的flush只刷新某些实体实例?

问题描述 投票:0回答:1

我的问题是EntityManager的flush方法正在将persist方法缓冲的所有操作写入数据库。没问题,但有时更改会在我不知情的情况下在其他上下文中写入。让我给你举个例子:

class ServiceA{
   public function __construct(private UserRepository $userRepository){}
   
   public function foo(){
      $user = $this->userRepository->find(1);
      $user->setName('newName');
      $this-userRepository->add($user, true); // second argument means that I do flush
   }
}

class ServiceB{
    public function __construct(
        private VisitRepository $visitRepository,
        private ServiceA $serviceA
    ){}

    public function bar(){
        $visit = $this->visitRepository->find(2);
        $visit->setSomething(2);
        $this->visitRepository->add($visit, false); // second argument means that I don't want to flush
        // Some other SELECTS here via the visitRepository, usage of setters and the persist method, but without flushing
        
        $this->serviceA->foo(); // Inside here the previous persisted instances in this context got flushed by the UserRepository's add method.

        $this->visitRepository->flush() // wrapper of EntityManager's flush method. which did not flush anything.
    }
}

Repository的add方法是EntityManager的persist和可选的flush的包装。像这样:

public function add(Visit $entity, bool $flush = false): void
    {
        $this->getEntityManager()->persist($entity);

        if ($flush) {
            $this->getEntityManager()->flush();
        }
    }

然后,在我的示例中,注入 EntityManager 或存储库来持久化和刷新并不重要。 所以,问题是 EntityManager(在存储库内,或者即使它作为 ServiceA 或 ServiceB 中的 EntityManager 注入)刷新所有内容,那么我的问题是,有时深层服务会刷新在我的应用程序的其他层中完成的更改,而无需我注意到。到目前为止,这对我来说还不是问题,但我可以在这里看到一个设计问题(在我这边)。

您如何解决这个问题?您有什么设计想法可以应用来解决这个问题吗?或者,有什么方法可以只将某些操作包装在刷新方法中,以便它只在数据库中写入上下文的操作?

我想像这样的解决方案来准确实体刷新的操作:

$otherContextEntityManager->persist($bar);

$thisContextEntityManager->persist($something)
$thisContextEntityManager->persist($foo);

$thisContextEntityManager->flush(); // Only $something and $foo get written in the DB

$otherContextEntityManager->persist($james);
$otherContextEntityManager->flush(); // Only $bar and $james get written in the DB.

也许将一些 EntityManager 作为非共享服务?

symfony doctrine-orm doctrine
1个回答
0
投票

Doctrine 的 EntityManager 刷新当前工作单元内托管实体的所有更改。

分离要从刷新中排除的实体 $this->entityManager->detach($entity);

注意:不要将分离的对象传递给持久操作。

© www.soinside.com 2019 - 2024. All rights reserved.