Hibernate的三种状态
hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别,比如瞬时状态就是刚new出来一个对象,还没有被保存到数据库中,持久化状态就是已经被保存到数据库中,离线状态就是数据库中有,但是session中不存在该对象。
图解
1.TestTransient(测试瞬态)
此时我们知道hibernate会发出一条insert的语句,执行完save方法后,该user对象就 变成了持久化的对象了
hibernate:insert into t_user (born,password,username) values (?,?,?)
2.TestPersistent01(测试持久化)
在调用了save方法后,此时user已经是持久化对象了,被保存在了session缓存当中,这时user又重新修改了属性值,那么在提交事务时,此时hibernate对象就会拿当前这个user对象和保存在session缓存中的user对象进行比较,如果这两个对象相同,则不会发送update语句,如果不同,则会发出update语句
Hibernate: insert into t_user (born, password, username) values (?, ?, ?)
Hibernate: update t_user set born=?, password=?, username=? where id=?
3.TestPersistent02
那么这个时候会发出多少条sql语句呢,还是同样的道理,在调用save方法后,u已经是持久化对象了,记住:如果一个对象已经是持久化状态了,那么此时对该对象进行各种修改,或多次调用update,save方法时,hibernate都不会发送sql语句,只有当事务提交时,hibernate才会拿当前这个对象与之前保存在session中的持久化对象比较,若不相同就发送一条update的sql语句,否则不会发送
Hibernate: insert into t_user (born, password, username) values (?, ?, ?)
Hibernate: update t_user set born=?, password=?, username=? where id=?
4.TestPersistent03
这里在调用了session.delete()方法后,此时u就会变成一个瞬态对象,因为此时的数据库中已经不存在该对象了,那么对u在进行各种修改操作德华,hibernate也不会发送任何的修改语句,这里只会有一条delete语句发生
Hibernate: delete from t_user where id=?
5.TestDetached04
saveOrUpdate()方法:如果对象是一个离线对象,那么在执行这个方法后,其实就是调用了update方法,如果对象是一个瞬时对象,则调用save方法,如果对象设置了ID值,例如u.setId(4),那么该对象会被假设当做一个离线对象,此时就会执行update操作。
Hibernate: update t_user set born=?, password=?, username=? where id=?
6.TestDetached05
此时我们的u1已经是持久化的对象了,保存在session缓存中,u2通过调用saveOrUpdate方法后也变成了一个持久化的对象,此时也会保存在session缓存中,这个时候session缓存中就存在了一个持久化对象有两个引用拷贝了,这个时候hibernate就会报错
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.xiaoluo.bean.User#3]
7.总结
①.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是瞬时对象(Transient)
②.瞬时对象调用save方法,或者离线对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句
③.离线对象就是,数据库存在该对象,但是该对象又没有被session所托管