Hibernate的三种状态:一个持久化类的实例可能处于三种状态的某一种,这三种状态的定义与持久化上下文(session)有关
1) 瞬态(transient):该实例从未与任何持久化上下文关联过,它没有持久化标识(相当于主键),简单来说就是刚刚new出来的实例对象,但不是从数据库中拿取的。
2)持久态(persistent):又称托管。实力目前与某个持久化上下文关联。它拥有持久化标识,并且可能在数据库中有一个对应的行。
3)脱管(detached):实例对象曾经与某个持久化上下文发生过关联,不过那个上下文被关闭了,或者这个实例是被序列化到这个进程中来的。它拥有持久化标识,并且数据库中可能存在一个对应的行。
三种状态之间的相互转换图:
get()和load()之间的区别:
同:都是加载一个持久化实例对象(persistent),
异:1、当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回Null;
2、当对象.hbm.xml配置文件<class>元素的lazy属性设置为true时,调用load()方法时则返回调回持久对象的代理类实例,此代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所有属性为Null,此时并没有打印输出Hibernate SQL语句,当代理类实例通过get()方法获取属性值时,hibernate才真正执行数据库查询。当在.hbm.xml文件中lazy=false,调用load()方法则立即执行数据库并直接返回实体类,并不返回代理类。而调用get()方法直接返回实体类
update()和saveOrUpdate以及Merge
update():是对瞬态(transient)或脱管(detached)的对象操作,对于transient状态对象的更新操作通常不产生效果,对于脱管对象是做了同步操作,即数据库的数据发生变化并且对象状态也变成了persistent对象。
SaveOrUpdate:也对瞬态(transient)或脱管(detached)的对象操作,至于是插入还是更新,则要根据id来判断,如果对象id==null,就执行save,如果对象id从来没有persistent,也执行save,如果对象是persistent对象的一个新的version,那么也save,其他情况执行update
Merge:将当前对象的状态保存到数据库中,并不会把该对象转换成持久化状态,例如现在有一个脱管A对象执行merge,hibernate会new一个B,或检索到一个持久化对象Bm并把我们提供的对象A的所有值拷贝到这个B,执行完成后B为persistent,而我们的A还是脱管状态