TypeORM中@BeforeRemove仅remove触发、softRemove不生效问题咨询
TypeORM软删除钩子触发逻辑及解决方案
问题原因解释
@BeforeRemove、@AfterRemove钩子本身是TypeORM为硬删除操作设计的专属钩子,按官方语义仅会在调用remove()、delete()这类执行DELETE语句、永久擦除数据库记录的接口时触发,属于正常设计逻辑。softRemove()、softDelete()属于软删除操作,本质是执行UPDATE语句给deletedAt字段赋值,不属于硬删除语义范畴,因此不会触发@BeforeRemove类钩子。
解决方案
TypeORM提供了软删除操作专属的生命周期钩子@BeforeSoftRemove、@AfterSoftRemove,专门对应软删除操作的触发时机,直接替换现有注解即可:
// 替换原@BeforeRemove注解 @BeforeSoftRemove() setDeletedInfo() { this.deleted_by = 'MyName' } // 原有软删除逻辑不需要改动 async remove(request: Request, _response: Response, next: NextFunction) { let userToRemove: any = await this.userRepository.findOne(request.params.id); return await this.userRepository.softRemove(userToRemove); }
兼容场景说明
如果你的业务同时需要兼容硬删除和软删除两种场景,可以把通用逻辑抽为公共方法,同时挂载到两个钩子上即可:
private fillDeletedBy() { this.deleted_by = 'MyName' } // 硬删除触发 @BeforeRemove() handleBeforeRemove() { this.fillDeletedBy() } // 软删除触发 @BeforeSoftRemove() handleBeforeSoftRemove() { this.fillDeletedBy() }
注意:如果使用的是
softDelete(id)方法而非softRemove(实体实例),因为该方法不会先查询实体实例,所以不会触发实体的生命周期钩子,此时需要先查询出实体再调用softRemove,或者手动在更新参数中传入deleted_by字段值。
内容的提问来源于stack exchange,提问作者Eder Ferraz
相关产品推荐
相关产品推荐

