You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony4中如何给子实体应用SoftDeletable软删除过滤规则

问题根因

该现象是Gedmo SoftDeletable扩展的默认行为:

  • 直接查询Posts实体时,全局注册的SoftDeletable过滤器会自动追加deletedAt IS NULL条件,因此已软删除数据会被正常过滤
  • 通过Users实体关联加载Posts时,默认的懒加载/预加载逻辑不会自动关联应用关联实体的过滤器,导致已软删除的帖子也会被返回。

解决方案

方案1:全局开启关联过滤(推荐)

如果你希望所有关联查询都自动应用软删除规则,直接修改Doctrine过滤器配置即可。
Symfony框架下修改config/packages/doctrine.yaml:

doctrine:
    orm:
        filters:
            softdeleteable:
                class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                enabled: true

原生Doctrine项目初始化EntityManager时添加配置:

$config = Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$em = EntityManager::create($dbParams, $config);
$em->getConfiguration()->addFilter('softdeleteable', \Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter::class);
$em->getFilters()->enable('softdeleteable');

该配置在Gedmo SoftDeletable v2.4及以上版本生效,无需额外配置即可自动作用于所有带软删除字段的关联实体。

方案2:手动在查询中添加过滤条件

如果仅需要在本次查询中过滤软删除帖子,无需全局修改,可以通过QueryBuilder手动关联查询:

return $this->em->getRepository(Users::class)
    ->createQueryBuilder('u')
    ->leftJoin('u.posts', 'p', 'WITH', 'p.deletedAt IS NULL')
    ->addSelect('p') // 预加载帖子,避免后续懒加载带出软删除数据
    ->where('u.id = :userId')
    ->setParameter('userId', $userId)
    ->getQuery()
    ->getOneOrNullResult();

方案3:在关联属性上绑定过滤器

如果希望仅Users和Posts的关联查询应用软删除过滤,其他关联不受影响,可以直接在Users实体的posts关联属性上添加Filter注解:

// App\Entity\Users.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Users
{
    // 其他属性

    /**
     * @ORM\OneToMany(targetEntity=Posts::class, mappedBy="user")
     * @ORM\Filter(name="softdeleteable")
     */
    private $posts;

    // 其他方法
}

注意事项

如果修改配置后依然能查询到已软删除的帖子,大概率是EntityManager的一级缓存已经缓存了之前加载的关联数据,调用$em->refresh($user)刷新实体即可解决。

内容的提问来源于stack exchange,提问作者Fares Karbia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:24:02