关于OID
hibernate缓存是一个map,他会根据OID作为缓存对象的key,我们的映射文件中<id>标签指定的属性值会作为OID
持久化对象的三种状态
为了方便理解,Hibernate为持久化对象定义了三个状态:
瞬时态:没有持久化标识OID,没有被纳入Session对象的管理
持久态:有持久化标识OID,已经被纳入Session对象的管理
托管态:有持久化标识OID,但没有被Session对象管理
用一个小示例来演示:
持久态的一个常见误解
需要注意的是,被纳入session对象的管理的持久态对象,仅仅是放入了session的一级缓存,却不一定会同步到数据库。(session中有一个PersistenceContext对象,本质就是一个map集合,一级缓存的数据就存在这里),如下图所示。
user被赋予了id
由上图可知,当执行到save()操作时,user已经被放到session中管理,并且已经拥有了id值,此时user是持久态的,但是现在数据库里并没有user的数据,因为还没有提交事务,所以持久态的对象并不一定就存在于数据库中。
关于持久态对象自动更新的能力
当在一个session中,对一个持久态的对象进行修改后,即使不执行update()方法,在事务提交时,也会会自动将修改后的数据同步到数据库。实现原理如下图:
这种机制实现的原理就是,session除了一级缓存区域,还有一个快照区域,当持久态对象第一次被放入一级缓存时,同时会在快照区域放一个这个对象的副本。如果接下来对对象进行了修改操作,一级缓存的数据会同时修改,但快照区域的对象不变。在事务提交时,会对这两个区域中的对象进行对比,如果相同,说明没有修改,直接提交。如果不同,会对改变的几个属性进行更新操作。