(Symfony 项目)学说错误:通过关系找到了新实体。运行 messageBus 异步时遇到(同步工作正常)

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

我知道很多人问过此类问题,但我相信我的问题不同,因为我只在尝试运行消息异步时遇到错误。

这只是一个供个人使用的项目,旨在尝试自己实现 Strava Premium 功能(我让它工作了,但我只是想更好地处理一切)。我是 symfony 的新手,所以我希望我能把问题和问题说清楚,以便有人给我一些提示。

在我的控制器中,我调用函数来开始从 strava api 加载活动,然后进行一些计算以保留新活动并刷新它们。我在运行消息时遇到此错误:

Handling "App\Message\StartLoadingMessage" failed: A new entity was found through the relationship 'App\Entity\Activities#user' that was not configured to cascade persist operations for entity: App\Entity\User@42792

我只在运行消息异步时遇到此错误。如果我同步运行它,它工作得很好。我希望能够异步运行它,因为如果我可以在该函数在后台运行时执行其他操作,那么用户体验会更好。

在我的控制器中,我像这样调用开始加载:

$user = $this->getUser();
$messageBus->dispatch(new StartLoadingMessage($user));

StartLoadingMessage 类只是标准消息类

StartLoadingMessageHandler类是这样的:

class StartLoadingMessageHandler implements MessageHandlerInterface
{
    public function __construct(private StravaRequests $startLoading)
    {
        $this->startLoading = $startLoading;
    }

    public function __invoke(StartLoadingMessage $message)
    {
        // Run the background task here
        $user = $message->getUser();
        $this->startLoading->startLoading($user);
    }
}

然后在实际的 startloading 函数中,我进行了一些 api 调用(没有错误)和一些计算,然后我尝试将新创建的活动添加到数据库中,如下所示:

            $newActivity = new Activity();
            $newActivity->setUser($user);
           
            $newActivity->setStravaId($activity['id']);
            $newActivity->setType($activity['type']);
            $newActivity->setRecordData($peaks);
            $this->em->persist($newActivity);
            $this->em->flush();

编辑 在此之后,我还如下更新用户:

 if (count($activities) > 0) {
            $latestEpochBeforeDate = 
          strtotime($activities[count($activities) - 1]['start_date']);
            $user->setLatestLoadedEpochDate($latestEpochBeforeDate);
            
            $this->em->flush();
        }

我不知道这是否是正确的方式,您需要创建一个新实体(在我的例子中为活动)并更新另一个(用户)

在“活动”实体中,我确保添加级联持久线:

 #[ORM\ManyToOne(inversedBy: 'activities', cascade:['persist'])]
    #[ORM\JoinColumn(nullable: false)]
    private ?User $user = null;

我尝试在 startloading 函数中的用户实体上显式调用 EntityManager#persist() ,但这也不起作用。

symfony asynchronous doctrine message-handlers
1个回答
0
投票

我猜问题出在异步运行时当前与 Doctrine 范围分离的用户实体。如果您的 Doctrine 版本接受它,纠正它的方法是使用以下代码:

$newActivity = new Activity();
$newActivity->setUser($user);
           
$newActivity->setStravaId($activity['id']);
$newActivity->setType($activity['type']);
$newActivity->setRecordData($peaks);

$this->em->merge($user);
$this->em->persist($newActivity);
$this->em->flush();

或者只需使用 UserRepository 和您拥有的用户 ID 查询用户并替换实际的 $user 变量。

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