Hibernate缓存机制和对象的三种状态
FJHHH Lv3

[TOC]

前言

说起来挺丢人的,工作也快一年了,还没有好好看过几乎天天接触的Hibernate。昨天在开发的时候又遇到了与对象状态和缓存有关的问题,于是找了两篇博客看了看,解决了问题,简单记录一下。

然后。。我用wordpress新搭的博客,欢迎访问:http://blog.fjhdtp.cn/

教程链接http://www.jianshu.com/p/56750622cac9

Hibernate的两层缓存机制

Hibernate有两层缓存机制,第一级是Session的缓存,第二级是SessionFactory的缓存。

Session的缓存不能被卸载,并且是事务范围的缓存(通常一个Session对应一个事务),这也是为什么懒加载需要在session关闭之前(session绑定在ThreadLocal)。

SessionFactory对象的生命周期和应用程序的过程相对应,因此SessionFactory的缓存是进程或集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。

Hibernate执行查找的过程

当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;

查不到,如果配置了二级缓存,那么从二级缓存中查;

如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。

Hibernate对象的三种状态

Hibernate的对象有三种状态:transient(临时)、persistent(持久)、detached(脱管)。

  • 临时态(transient) 临时态的对象没有被Hibernate的缓存所管理,并且在数据库中没有与之相对应的数据。
  • 持久态(persistent) 持久态的对象被Hibernate的缓存所管理,并且在数据库中有与之对应的数据。
  • 脱管态(detached) 脱管态的对象脱离了Hibernate的缓存管理,并且在数据库中有与之对应的数据。

遇到的问题

我有一个Table A, 我从前台获取一些数据,放入对象b中, 如果A中有对应的数据, 则update(),如果没有则save()。结果我在程序中获得了持久态的对象a(当然a、b都是同一个类的对象)后,试图将a的OID赋值给b,然后update()脱管态的b,结果就报错了。

之后我试图使用merge()来解决这个问题,结果每次都会新增一条数据。

稍稍研究了下,只要把临时态对象的数据拷贝到持久态对象中,然后保存持久态对象就可以了。

参考

Hibernate 缓存机制

Hibernate中对象的三个状态解析

 Comments