在用Hibernate的时候,时不时会因为没有处理好实体对象的状态而犯一些莫名其妙的异常,在这里对实体对象的各种状态整理一下,希望能有所帮助。
Hibernate实体对象,即指Hibernate O/R影射关系中的域对象 即O/R中的"O"。在Hibrenate实体对象的生命周期中存在着三中状态,即:
1:自由状态(Transient)。
2:持久状态(Persistent)。
3:游离状态(Detached)。
1:自由状态(Transient)
自由状态(Transient),是指实体对象在内存中自由存在,他与数据库的记录无关。如:
- TUser user = new TUser();
- user.setName("MyName");
TUser user = new TUser();
user.setName("MyName");
这里的user对象只是一个非常普通的java对象,与数据库中的记录没有任何关系。
2:持久状态(Persistent)
持久状态(Persistent),即实体对象处于Hibernate框架的管理状态,实体对象被纳入Hibernate的实体容器中管理。处于
持久状态的对象,其更变将由Hibernate固化到数据库中。如:
-
- TUser user_1 = new TUser();
- TUser user_2 = new TUser();
-
- user_1.setName("Name_1");
- user_2.setName("Name_2");
-
- Transaction tx = session.begintransaction();
- session.save(user_1);
-
-
-
- tx.commit();
-
-
//创建两个处于自由状态的实体对象。
TUser user_1 = new TUser();
TUser user_2 = new TUser();
user_1.setName("Name_1");
user_2.setName("Name_2");
Transaction tx = session.begintransaction();
session.save(user_1);
//通过session的save方法,user_1对象已经被纳入Hibernate的实体管理容器,处于持久化状
//态(Persistent),这时候对user_1对象的任何修改都将被同步到数据库中。
tx.commit();
//而user_2仍然才处于自由状态(Transient),不受Hibernate框架的管理。
从上面看到,处于
自由状态的实体对象,可以通过Hibernate的Session.sava方法转化为
持久状态。
除了用Session.save方法外,还可以通过其他方法来获取一个
持久状态的对象,那就是直接通过Hibernate加载的对象,通过Session.load方法,可以直接加载一个处于
持久状态的实体对象。如下:
- TUser user = Session.load(TUser.class,new Integer(1));
-
-
TUser user = Session.load(TUser.class,new Integer(1));
//在load方法没返回之前,就已经先把对象纳入Hibernate的管理范围,所以这里的user
//已经处于持久状态。
从上面的代码可以看出,处于
持久状态的实体对象一定要和Session关联,并处于该Session的有效期内。
3:游离状态(Detached)
处于
持久状态的实体对象,在其关联的Session关闭以后,此实体对象就处于
游离状态,
- TUser user = new TUser();
- user.setName("name_1");
- Transaction tx = session.begintransaction();
- session.save(user);
- tx.commit();
- session.close();
-
-
TUser user = new TUser();
user.setName("name_1");
Transaction tx = session.begintransaction();
session.save(user);//把自由状态的实体对象user转为持久状态,
tx.commit();
session.close();
//session关闭以后,处于持久状态的实体对象user将转为游离状态。
//因为此时user已经和session脱离关系。
由上面可以看到实体对象的
游离状态是在对象和它所寄宿的Session脱离关系后形成的,但处于
自由状态的实体对象也没有和任何session有关联,那么他们两者有什么区别呢?关键的就在我们对
自由状态的实体对象执行了Session.save方法,
当我们执行
- TUser user = new TUser();
TUser user = new TUser();
时,我们只是创建了一个普通的对象,他并没有和数据库里的任何一条记录对应,当我们执行
Session.save以后,Hibernate就为user设置了一个主键,就是user.Id属性,通过这个属性,Hibernate就把user对象和数据库里的记录关联起来,所以
自由状态和
游离状态的基本区别就是 处于
游离状态的实体对象,在数据库里有对应的记录,因此它可以通过和session关联再次转为
持久状态。
三种状态的转化
自由状态-->持久状态:可以通过Session.sava方法来转换。
持久状态-->游离状态:可以通过Session.close方法来关闭session,获取游离状态的对象
持久状态-->自由状态:可以通过Session.delete方法来删除实体对象对应的数据库记录,使实体对象处于自由状态。
补充一下,有时可能会想,可以通过认为的个处于
自由状态的实体对象设置一个Id值
user.Id=1
,来人为的创建一个
游离状态的对象。
这里注意一点,我们可以人为地给实体对象设置Id值,我我们无法知道这个ID值在数据库里有没有对应的记录,如果没有,就算我们人为地设置了Id,也不能说一个有ID的实体对象就是一个
游离状态的对象。