和数据库关联的对象有三种状态:瞬时,持久,脱管。
瞬时:在数据库中还没有与该对象关联的记录,仅仅是一个普通的对象而已,超过作用域,就会被回收。一般都是new出来的对象,并且还没有与session建立联系。
持久:与session建立了联系,并且在数据库中已经有了和该对象关联的记录,并且session没有关闭,事务没有提交,处于持久状态的对象,其状态改变,hibernate会检测到,在进行提交时,会影响到数据库中该对象对应的记录。但是,应注意,若是session没有关闭,但事务已经提交,那么当前对象仍然处于持久状态,不过,对象状态的改变不会影响到数据库,只要再开启一个事务,在提交时,就会影响到数据库了。
脱管:数据库中已有记录和这个对象对应,但是当前已经和session失去了关联,此时,若对象发生改变,不会影响到数据库。
如下例:
package com.suo.test;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.Session;
import com.suo.domain.User;
import com.suo.hibernate.HibernateUtil;
public class Test {
public static void main(String[] args) {
User user=new User();
user.setBirthday(new Date());
user.setName("suo");
//此时的user对象是瞬时状态(Transient)
addUser(user);
//此时的user对象是脱管的(Detached)
}
public static void addUser(User user){
Session session=null;
Transaction transaction=null;
try{
session=HibernateUtil.getSession();//获得一个连接
transaction=session.beginTransaction();//开启一个事务
session.save(user);
user.setName("piao");
//此时的user对象是持久的(Persistent)
transaction.commit();/*设置为自动提交,因为hibernate默认的设置为不自动提交,这时候使用的数据库引擎为InnoDB,支持事务*/
}catch(HibernateException e){
if(transaction!=null){
transaction.rollback();
}
e.printStackTrace();
}finally{
if(session!=null){
session.close();
}
}
}
}
注意:在addUser方法中,在session.save(user)之后,对象的状态改变了,由于此时还没有进行事务的提交,并且还和session保持着关联,所以,对象此时处于持久状态,所以,user名字的改变,也会反映到数据库中,数据库中的name,不是之前的suo,而是修改之后的piao。
这三种状态之间转换的关系如下图:
(摘自李勇老师的课件)