Symfony 3.4 MongoDB项目Softdeleteable过滤器失效问题
我之前在做Symfony项目时也碰到过类似的软删除过滤器失效情况,结合你的描述,给你几个具体的排查和解决步骤:
1. 确认Doctrine MongoDB ODM的过滤器是否启用
这是最容易忽略的关键!即使配置了Stof扩展,还需要在Doctrine MongoDB的文档管理器里明确启用softdeleteable过滤器。打开你的config.yml(或专门的doctrine_mongodb.yml),检查是否有以下配置:
doctrine_mongodb: document_managers: default: # 其他已有配置... filters: softdeleteable: class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter enabled: true
如果没有这段配置,添加后执行php bin/console cache:clear清空缓存再测试。
2. 检查Stof Doctrine Extensions的MongoDB配置
确保你在config.yml里的Stof扩展配置是针对MongoDB的,不要只配置ORM部分:
stof_doctrine_extensions: default_locale: en_US # 必须配置mongodb节点,而非仅orm节点 mongodb: default: softdeleteable: true
很多人会不小心只配置了orm节点,但你用的是MongoDB,所以必须在mongodb节点下启用软删除。
3. 验证文档类的注解是否正确
检查你的MongoDB文档类,确保:
- 正确添加了
@Gedmo\SoftDeleteable注解并指定fieldName为deletedAt deletedAt字段的类型映射为date类型
示例代码:
use Gedmo\SoftDeleteable\Traits\SoftDeleteableDocument; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; use Gedmo\Mapping\Annotation as Gedmo; /** * @MongoDB\Document() * @Gedmo\SoftDeleteable(fieldName="deletedAt") */ class YourDocument { // 推荐使用Trait简化代码 use SoftDeleteableDocument; // 若不用Trait,手动定义字段需保证映射正确: /** * @MongoDB\Field(type="date") */ private $deletedAt; // 其他字段和方法... }
4. 排查是否有代码手动禁用了过滤器
检查业务代码中是否存在手动禁用软删除过滤器的逻辑,比如:
$dm = $this->get('doctrine_mongodb')->getManager(); $dm->getFilterCollection()->disable('softdeleteable');
如果有这样的代码,会导致当前请求内的查询跳过软删除过滤,需要删除或调整逻辑。
5. 确认扩展版本兼容性
Symfony 3.4对应的stof/doctrine-extensions-bundle版本建议为~1.3或^1.4,避免版本不兼容问题。查看composer.json,若版本不符,执行:
composer require stof/doctrine-extensions-bundle:~1.3
更新依赖后重新测试。
6. 确保查询使用Doctrine ODM方法
如果你直接使用原生MongoDB查询(如调用MongoClient),而非Doctrine ODM的createQueryBuilder或find方法,软删除过滤器不会生效。必须使用Doctrine ODM提供的查询接口,过滤器才会自动应用。
按照以上步骤逐一排查,应该就能解决软删除过滤器失效的问题了。
内容的提问来源于stack exchange,提问作者Diana

