doctrine-orm - Doctrine2:PreFlush 钩子超时
问题描述
我有两个实体。
首先是我的父实体,它具有名为 productsCount 的属性。这个实体有另一个实体链接到它,称为 Store 和 store 已链接 Room。每个房间可以有多个产品。
当我编辑分配给房间的产品时,我想更新父 productsCount 以存储所有商店所有房间中所有产品的计数。
我有一个可以计算计数的 SQL 查询。每次我用新产品更新房间时,我都需要这样做。这是通过在 Room 实体上使用 EntityListener 的 preFlush 钩子完成的。
preFlush 钩子被正确触发,但由于某种原因它会超时。
这是 preFlush 代码示例
public function preFlush(Room $room, PreFlushEventArgs $args)
{
$em = $args->getEntityManager();
$parent = $room->getStore()->getParent();
$rsm = new ResultSetMapping();
$rsm->addScalarResult('COUNT(product_id)', 'count');
$query = $em->createNativeQuery(
'select COUNT(product_id)
from room_product where `room_id` in
(select id from room where store_id in
(select id from store where parent_id = :parentId))', $rsm);
$query->setParameter('parentId', $parent->getId());
$result = $query->getOneOrNullResult();
$parent->setNumberOfServices($result['count']);
$em->persist($parent);
$em->flush();
}
查询应该可以正常工作,所以我认为它与刷新和持久化父实体有关。
有任何想法吗?
解决方案
因此,经过几个小时的战斗,我能够找到解决方案。
事实证明我不必坚持,也不必刷新更改。解决方案是使用工作单元重新计算 $parent 上的更改,然后学说将自行刷新它们。我还必须更改计算产品的方式,因为在 preFlush 阶段更改尚未在数据库中,因此查询将无法正常工作。这就是为什么我通过遍历关系树来手动计算它们。
这是一个代码示例。
public function preFlush(Room $room, PreFlushEventArgs $args)
{
$em = $args->getEntityManager();
$numOfProducts = 0;
$parent = $room->getStore()->getParent();
foreach($parent->getStores() as $store) {
foreach($store->getRooms() as $room) {
$numOfServices += count($room->getProducts());
}
}
$parent->setNumberOfProducts($numOfProducts);
$classMetadata = $em->getClassMetadata(get_class($parent));
$em->getUnitOfWork()->computeChangeSet($classMetadata, $parent);
}
推荐阅读
- php - PHP 在一个用户上插入数据库,但不在另一个具有相同权限的用户上
- regex - 改进有效的正则表达式
- kubernetes - Kubernetes 网络策略出口端口
- git - 为什么我的 git 代理配置不起作用?我确定我已正确设置它,但它仍然无法正常工作
- unit-testing - 使用指定的初始化器语法跟踪用户定义的“结构”成员
- datetime - 如何在输入控件中获取 java.sql.Timestamp 的默认值表达式
- firebase - 使用颤振在 Firestore 上执行 CRUD 操作的最佳方法是什么?
- java - 无法确定任务 ':myapplication:preHuaweiDebugBuild' 的依赖关系
- angular7 - 如何将值从一个组件更新到另一个组件?
- c# - JsonConvert 反序列化十进制到 jtoken 将其转换为科学数,我如何将其转换回十进制?