Hibernate OGM加@Version删除MongoDB实体仅保留_id字段问题
问题成因
这个现象是Hibernate OGM针对带@Version乐观锁注解的实体执行删除时的实现逻辑导致的:
- Apache Deltaspike Data的
attachAndRemove方法会先将传入的脱管实体合并(merge)到持久化上下文,再执行删除操作。 - 带
@Version注解的实体删除需要做乐观锁校验,旧版本Hibernate OGM的MongoDB方言实现中,为了校验版本号是否匹配,会先生成一条updateOne语句:- 执行条件为
_id = 实体ID and version = 实体当前版本号 - 执行内容是清空文档所有非
_id字段,同时将版本号+1,用来完成乐观锁的冲突校验 - 该版本的实现存在缺陷,更新校验完成后没有生成后续的
deleteOne语句执行实际的文档删除,最终就只剩只带_id的空文档。
- 执行条件为
- 去掉
@Version注解后,不需要做乐观锁校验,Hibernate OGM会直接生成按_id删除的deleteOne语句,文档会被完整移除。
解决方案
- 优先升级Hibernate OGM到最新稳定版,该bug在后续迭代中已经被修复。
- 如果无法升级版本,可以自定义Repository删除逻辑:
- 直接编写JPQL批量删除语句:
DELETE FROM MyEntity e WHERE e.id = :id,这类语句会绕过乐观锁校验直接生成删除命令。 - 删除前先按ID查询出托管状态的实体,再调用
remove方法执行删除,也可以规避该问题。
- 直接编写JPQL批量删除语句:
内容的提问来源于stack exchange,提问作者kem
相关产品推荐
相关产品推荐

