关于Hibernate更新后, 获取的值仍是旧的问题

最近在更新商品库存的时候遇到一个诡异的问题:

1.取出本地商品信息,

2.查询总库库存, 将库存更新到本地

3.再取出商品和库存, 更新库存预警信息

结果在第三步骤出了问题: 取出来的库存是旧的, 不是刚更新的库存???

JAVA类 SkuRepo:

@Modifying
@Query(value = "update Sku set inv=:inv where id=:id")
void updateInv(@Param("id") String id, @Param("inv") int inv);

JAVA类 SkuServie:

//获取sku
Sku slSkuDB = skuRepo.findById("123456").orElse(null);
//获取总库库存
int inv = 0;
........
//更新库存
skuRepo.updateInv(slSkuDB.getId(), inv);
//发送事件
Event.publish(slSkuDB.getId());

JAVA类 SkuInvListener:
//监听库存改变事件
public void onInvChange(String skuId){
Sku slSkuDB = skuRepo.findById("123456").orElse(null);
int inv = slSkuDB.getInv();
................这里获取的库存是旧的
}

问题分析:

经过调试, 发现库存肯定更新成功的.

那么事件监听中, Sku对象不是从数据库取的, 而是上次Hibernate中已有的对象.

而且updateInv并没有更新Hibernate的缓存.

验证:

无奈, 只能断点debug: 发现”SkuServie”获取的Sku和”SkuInvListener”获取的Sku, 指向的Hibernate对象是同一个, 而且inv还是旧值. HQL语句也不会触发缓存更新!!!

处理:

更新库存
  skuRepo.updateInv(slSkuDB.getId(), inv);
改成:
  slSkuDB.setInv(inv);
  skuRepo.save(slSkuDB);

总结:

使用Hibernate一定要实时关注它的缓存问题(一级缓存和二级缓存)

更新对象,最好用Hibernate自带的更新操作, 任何Native SQL和HQL都不会同步到缓存中.