hibernate持久化类和一级缓存的关系?

灵魂重新 2014-03-11 09:18:55
最近学习hibernate框架,看到hibernate对象的状态和 session的一级缓存的机制有点异曲同工之妙。



而同时
关于session的缓存又有下面一段话
怎么样把数据存放到一级缓存中?
利用session.save/update/load/get方法都可以存放在一级缓存中
session.evict方法可以把一个对象从一级缓存中清空?
利用session.clear方法可以把session中的所有的数据清空

让我实在是不得不怀疑所谓的持久化状态就是放在一级缓存中。

好了问题来了,一级缓存的生命周期就是session的生命周期,当session关闭的时候,相对应的一级缓存中的数据也就消失了,那么看下面这个例子。


@Test
public void test(){
Session session = sessionFactory.openSession();
// Transaction transaction = session.beginTransaction();
// Person p1 =(Person)session.load(Person.class, 1L);
Person p1 =(Person)session.get(Person.class, 1L);
// transaction.commit();
session.close();
System.out.println(p1.getPsex());
}
OUTPUT:nan 成功输出
我不禁疑惑,这个p1到底有没有放在一级缓存中?
如果有,session 关闭后为什么还能使用?
如果没有,首先确定没关闭之前是放在一级缓存中,那么关闭之后缓存消失,它跑哪里去了?
...全文
92 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
灵魂重新 2014-03-12
  • 打赏
  • 举报
回复
引用 2 楼 java_liyi 的回复:
我一直以来都是这样认为的:缓存不是内存,缓存你可以把它看成一个寄存器,对象在session关闭后 变为游离态,然后在内存中放着而已
你这个解释 很有意思。寄存器,恩不错
灵魂重新 2014-03-12
  • 打赏
  • 举报
回复
引用 3 楼 wlwlwlwl015 的回复:
我觉得你没有理解什么缓存。 抛开hibernate不说,什么是缓存?是一种为了提高数据读取效率的一种介质。是介质,缓存的数据是拷贝而来的。你明白了这一点,再给你说你第二个问题, Person p1 =(Person)session.get(Person.class, 1L); 这句代码,直接就持久化了p1对象,就是说执行了SQL查询,很明显你还没理解持久化的概念, 说白了,持久化就是数据库有,sesison缓存也有。 你已经用一个实体对象p1接受了你查询的对象,那么你下面打印当然有东西,你system语句打印的又不是你缓存的东西,可以说和你的缓存毫无关系啊。缓存本身就是拷贝来的数据,你打印的是你持久化的对象,二者毫不相干,明白了吧。
OK 点清楚了
小灯光环 2014-03-11
  • 打赏
  • 举报
回复
我觉得你没有理解什么缓存。 抛开hibernate不说,什么是缓存?是一种为了提高数据读取效率的一种介质。是介质,缓存的数据是拷贝而来的。你明白了这一点,再给你说你第二个问题, Person p1 =(Person)session.get(Person.class, 1L); 这句代码,直接就持久化了p1对象,就是说执行了SQL查询,很明显你还没理解持久化的概念, 说白了,持久化就是数据库有,sesison缓存也有。 你已经用一个实体对象p1接受了你查询的对象,那么你下面打印当然有东西,你system语句打印的又不是你缓存的东西,可以说和你的缓存毫无关系啊。缓存本身就是拷贝来的数据,你打印的是你持久化的对象,二者毫不相干,明白了吧。
java_liyi 2014-03-11
  • 打赏
  • 举报
回复
我一直以来都是这样认为的:缓存不是内存,缓存你可以把它看成一个寄存器,对象在session关闭后 变为游离态,然后在内存中放着而已
灵魂重新 2014-03-11
  • 打赏
  • 举报
回复
引用 楼主 a1294246096 的回复:
最近学习hibernate框架,看到hibernate对象的状态和 session的一级缓存的机制有点异曲同工之妙。 而同时 关于session的缓存又有下面一段话 怎么样把数据存放到一级缓存中? 利用session.save/update/load/get方法都可以存放在一级缓存中 session.evict方法可以把一个对象从一级缓存中清空? 利用session.clear方法可以把session中的所有的数据清空 让我实在是不得不怀疑所谓的持久化状态就是放在一级缓存中。 好了问题来了,一级缓存的生命周期就是session的生命周期,当session关闭的时候,相对应的一级缓存中的数据也就消失了,那么看下面这个例子。 @Test public void test(){ Session session = sessionFactory.openSession(); // Transaction transaction = session.beginTransaction(); // Person p1 =(Person)session.load(Person.class, 1L); Person p1 =(Person)session.get(Person.class, 1L); // transaction.commit(); session.close(); System.out.println(p1.getPsex()); } OUTPUT:nan 成功输出 我不禁疑惑,这个p1到底有没有放在一级缓存中? 如果有,session 关闭后为什么还能使用? 如果没有,首先确定没关闭之前是放在一级缓存中,那么关闭之后缓存消失,它跑哪里去了?
当然我最后还得debug了一下 Hibernate: select person0_.pid as pid0_0_, person0_.pname as pname0_0_, person0_.psex as psex0_0_ from Person person0_ where person0_.pid=? nan 很明显这个person在session 关闭之后依旧存在,所以只向数据库进行一条插入语句,没有随着缓存的消失而不见。 问题很明显了,缓存是随着session消失而消失的,缓存中的内容则不会随着缓存消失而消失。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧