Hibernate Evict方法无法逐出一级缓存对象问题求助
Hibernate一级缓存逐出问题的解决方案
你的代码核心问题
- evict操作时机错误:你先查询出对象并拿到内存实例,再调用
session.evict(pList.get(0))——这只是从Hibernate的一级缓存中移除该对象的引用,但你返回的依然是已经加载到内存的旧对象实例。 - 未强制查询从数据库拉取数据:即使逐出了缓存对象,若Session未关闭,第二次查询Hibernate仍会优先检查缓存,不会主动去数据库取最新数据。
修正后的实现方案
方案1:先逐出缓存再查询
先移除缓存中的目标对象,再执行查询,确保从数据库获取最新数据:
Person clearCache() { // 先获取缓存中的对象(如果存在)并逐出 Person cachedPerson = session.createQuery("select p from Person p", Person.class).uniqueResult(); if (cachedPerson != null) { session.evict(cachedPerson); } // 重新查询,此时会从数据库加载最新数据 return session.createQuery("select p from Person p", Person.class).uniqueResult(); }
方案2:用refresh同步数据库最新状态
如果需要保留Session中的对象引用,但要同步数据库的最新修改,直接用refresh方法:
Person clearCache() { Person person = session.createQuery("select p from Person p", Person.class).uniqueResult(); // 强制从数据库刷新对象的所有字段 session.refresh(person); return person; }
方案3:清空整个Session缓存
如果不需要保留Session中其他缓存的对象,可以直接清空整个一级缓存:
Person clearCache() { // 清空当前Session的所有缓存对象 session.clear(); return session.createQuery("select p from Person p", Person.class).uniqueResult(); }
方案4:查询时忽略缓存
在查询时设置CacheMode.IGNORE,强制Hibernate跳过缓存直接查询数据库:
Person clearCache() { List<Person> pList = session.createQuery("select p from Person p", Person.class) .setCacheMode(CacheMode.IGNORE) .getResultList(); return pList.get(0); }
关键知识点
- Hibernate一级缓存是Session级别的缓存,只要Session未关闭,缓存的对象就会驻留。
evict()移除单个对象,clear()清空整个Session缓存。 - 默认查询会优先从一级缓存取对象,要强制获取最新数据,必须主动触发缓存逐出、对象刷新,或者让查询忽略缓存。
内容的提问来源于stack exchange,提问作者RathanaKumar
相关产品推荐
相关产品推荐

