了解Hibernate持久化对象的状态可以很好的帮助我们理解hibernate_Session的核心方法,但是如果想要明白持久化对象在Hibernate中是怎么分类的,我们首先需要搞清楚什么是OID!
在关系数据库中,主键用来识别记录,并保证每天记录的唯一性。在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两变量引用的对象是否相等。Hibernate为了解决两者之间的不同,使用对象标识符(OID)来标识对象的唯一性。OID是关系数据库中主键在Java对象模型中的等价物。在运行时,Hibernate根据OID来维持Java对象和数据库中的对应关系。如下所示:
Transaction tx = session.beginTransaction();User user1 = (User)session.load(User.class,new Long(1));
User user2 = (User)session.load(User.class,new Long(1));
User user3 = (User)session.load(User.class,new Long(3));
应用程序在执行上述代码时,第一次OID为1的对象,从数据库中查找ID为1的记录,然后创建想要的User实例,并把它保存到session的缓存中,最后将该实例的引用赋值给变量user1,第二次加载OID为1的对象时,直接把session缓存中的OID为1的实例的引用赋值给user2,因此user1=user2的结果为true。
我们大致可以把Hibernate中的持久化对象的状态分为四种:临时状态,持久化状态,删除状态,游离状态。
1、临时状态(Transient)
在使用代理主键的情况下, OID 通常为 null
不处于 Session 的缓存中
在数据库中没有对应的记录
2、持久化状态(也叫”托管”)(Persist)
OID 不为 null
位于 Session 缓存中
若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应
Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
3、删除状态(Removed)
在数据库中没有和其 OID 对应的记录
不再处于 Session 缓存中
一般情况下, 应用程序不该再使用被删除的对象
4、游离状态(也叫”脱管”) (Detached)
OID 不为 null
不再处于 Session 缓存中
一般情况下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录