如何强制TypeORM调用repository.save()时即使无字段变更也触发更新
问题原因
TypeORM 的 @BeforeUpdate 钩子以及 EntitySubscriber 中的 beforeUpdate 方法默认触发逻辑受底层脏检查机制限制:只有当实体字段和数据库中存储的快照对比存在实际变更时,才会生成 UPDATE 语句,进而触发对应更新钩子。
可行解决方案
方案1:使用
beforeFlush钩子替代beforeUpdatebeforeFlush是每次 UnitOfWork 执行 flush 操作时都会触发的钩子,不受脏检查结果限制,只要调用repository.save()触发了持久化流程就会执行,适配每次都要加密的需求,示例代码如下:// 在你的Subscriber类中添加该方法 public beforeFlush(uow: UnitOfWork): void { // 遍历本次持久化涉及的所有需要加密的实体 for (const entity of uow.getManagedEntities()) { if (entity instanceof YourTargetEntity) { encryptData(entity); } } }方案2:调用save时强制标记实体为脏
如果你需要保留beforeUpdate的现有逻辑,可在每次调用save前手动标记实体存在变更,强制触发更新流程:// 保存前执行,强制标记实体为变更状态 dataSource.manager.getRepository(YourEntity).merge(targetEntity, {}); // 再执行save,即可触发beforeUpdate钩子 await repository.save(targetEntity);方案3:加密逻辑上移到业务层封装
你可以封装实体的持久化方法,每次调用保存前主动执行加密,完全不依赖TypeORM钩子,可控性更高:// 封装统一的实体保存方法 async function saveEncryptedEntity<T>(repo: Repository<T>, entity: T): Promise<T> { encryptData(entity); return repo.save(entity); }
内容的提问来源于stack exchange,提问作者Karry Bee
相关产品推荐
相关产品推荐

