我知道很多人问过此类问题,但我相信我的问题不同,因为我只在尝试运行消息异步时遇到错误。
这只是一个供个人使用的项目,旨在尝试自己实现 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() ,但这也不起作用。
我猜问题出在异步运行时当前与 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 变量。