Hibernate的三种状态

时间:2022-09-18 18:37:15

在网上看到一篇文章写得很好,直接拿过来看这个了:

下面是转自:http://www.blogjava.net/asktalk/archive/2006/01/18/28548.html的一篇文章

在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的。对于理解hibernate,JVM和sql的关系有更好的理解。对于需要持久化的JAVA对象,在它的生命周期中有三种状态,而且互相转化。

1,  临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

2,  持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

3,  游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。
特点:已经持久化,但不在Session
缓存中。处于此状态的对象叫游离对象;

×√

临时状态

(Transient)

持久化状态

(Persistent)

游离状态

(Detached)

是否处于Session缓存中

×

×

数据库中是否有对应记录

×

状态转换图,结束官方的和转载作者的

Hibernate的三种状态

Hibernate的三种状态


游离对象和临时对象异同:

两者都不会被Session关联,对象属性和数据库可能不一致;

游离对象有持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;

Hibernate和SQL的关系:

在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;

下面举例说明:
一,Session.save(user)运行机理。
1,把User对象加入缓存中,使它变成持久化对象;
2,选用映射文件指定的标识生成ID;
3,
在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库;

注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;

二,Session.delete(user)运行过程。
如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:
在Session清理缓存时候;
如果user是游离对象:
1,将user对象和Session关联,使之成为持久化对象;
2,然后按照user 是持久化对象的过程执行;



下面是孔浩老师讲课的代码:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 package org.zttc.itat.test;   import java.text.SimpleDateFormat;   import org.hibernate.Session;import org.junit.Test;import org.zttc.itat.model.User;import org.zttc.itat.util.HibernateUtil;   public class TestStatus {    private static final SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd");    @Test    public void testTransient() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setBorn(sdf.parse("1976-2-3"));            u.setUsername("zxl");            u.setNickname("赵晓六");            u.setPassword("123");            //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有            //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态            session.save(u);                           session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent01() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setBorn(sdf.parse("1976-2-3"));            u.setUsername("zxq");            u.setNickname("赵晓七");            u.setPassword("123");            //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有            //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态            session.save(u);            //此时u是持久化状态,已经被session所管理,当在提交时,会把session中的对象和目前的对象进行比较            //如果两个对象中的值不一致就会继续发出相应的sql语句            u.setNickname("赵晓其");            //此时会发出2条sql,一条用户做插入,一条用来做更新            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent02() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setBorn(sdf.parse("1976-2-3"));            u.setUsername("zxq");            u.setNickname("赵晓八");            u.setPassword("123");            session.save(u);            u.setPassword("222");            //该条语句没有意义            session.save(u);            u.setNickname("赵晓吧");            //没有意义            session.update(u);            u.setBorn(sdf.parse("1988-12-22"));            //没有意义            session.update(u);            //持久化状态(缓存中),事务提交的时候,才执行语句            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent03() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setBorn(sdf.parse("1976-2-3"));            u.setUsername("zxq");            u.setNickname("赵晓九");            u.setPassword("123");            session.save(u);            /*             * 以下三条语句没有任何意义             */            session.save(u);            session.update(u);            session.update(u);            u.setUsername("zxj");            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent04() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            //此时u是Persistent            User u = (User)session.load(User.class10);            //由于u这个对象和session中的对象不一致,所以会发出sql完成更新            u.setUsername("aaa");            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent05() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            //此时u是Persistent            User u = (User)session.load(User.class10);            session.getTransaction().commit();            session.beginTransaction();            u.setUsername("123");            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testPersistent06() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            //此时u是Persistent            User u = (User)session.load(User.class11);            u.setUsername("123");            //清空session            session.clear();            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach01() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setId(10);            u.setNickname("abc");            //当执行save的时候总是会添加一条数据,此时id就会根据Hibernate所定义的规则来生成(10是无效的)            session.save(u);            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach02() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setId(10);            //完成update之后也会变成持久化状态            session.update(u);            u.setBorn(sdf.parse("1998-12-22"));            u.setNickname("aaa");            u.setUsername("111");            //会发出一条sql            session.update(u);            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach03() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setId(10);            //完成update之后也会变成持久化状态            session.update(u);            u.setBorn(sdf.parse("1998-12-22"));            u.setNickname("aaa");            u.setUsername("111");            //会抛出异常            u.setId(333);            //会发出一条sql            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach04() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();            u.setId(10);            //现在u就是transient对象            session.delete(u);            //此时u已经是瞬时对象,不会被session和数据库所管理            u.setNickname("abc");            //只会发出一条delete语句            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach05() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            User u = new User();//         
u.setId(110);
            u.setNickname("abc");            //如果u是离线状态【数据库中有,有ID就认为是,但session缓存中没有】就执行update操作,如果是瞬时状态就执行Save操作            //但是注意:该方法并不常用            session.saveOrUpdate(u);            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }           @Test    public void testDetach06() {        Session session = null;        try {            session = HibernateUtil.openSession();            session.beginTransaction();            //u1已经是持久化状态            User u1 = (User)session.load(User.class11);            System.out.println(u1.getNickname());            //u2是离线状态            User u2 = new User();            u2.setId(11);            u2.setPassword("12223");            //此时u2将会变成持久化状态,在session的缓存中就存在了两份同样的对象,在session中不能存在两份拷贝,否则会抛出异常//         
session.saveOrUpdate(u2);
            //merge方法会判断session中是否已经存在同一个对象,如果存在就将两个对象合并            session.merge(u2);            //最佳实践:merge一般不用            session.getTransaction().commit();        catch (Exception e) {            e.printStackTrace();            if(session!=null) session.getTransaction().rollback();        finally {            HibernateUtil.close(session);        }               }}