Hibernate持久化物件的生命週期詳解
阿新 • • 發佈:2019-01-10
在Hibernate中,持久化物件在被操作過程中可以分為三個時期,這三個時期是和Session的週期相關的,因為Hibernate中的操作都是基於Session完成的。所以Session物件的生命週期也關係著持久化物件的生命週期。
持久化物件的生命週期有三種,分別是瞬時態(Transient),持久態(Persistent)和脫管態(Detached)。
瞬時態的物件是剛剛用new關鍵字創建出來的,還沒有進入Session,此時的物件沒有和資料庫中的記錄對應。示例程式碼如下:
Java程式碼
這時user就是出於瞬時態的持久化物件。
通過Session物件的save(),persist()或者saveOrUpdate()方法進行儲存處於瞬時態的物件後,該物件就變為持久態。此時Session中已經存在該物件,並且對應資料庫中的一條記錄。值得注意的是在Session物件失效之前,對持久態物件的任何修改,在呼叫Session物件的close()方法或者Transaction物件的commit()方法之後,資料庫表中對應的資料會同時更新。示例程式碼如下:
Java程式碼
在呼叫save()方法後,持久化物件user就變為持久態,但是執行了commit()方法之後,資料庫操作才會進行,這點必須明確。所以在資料庫操作執行之前對持久化物件的修改Hibernate可以感知。
而且Session物件的get()和load()方法也可以返回一個持久態的物件,這個物件代表資料庫表中的一條記錄。
脫管態,這個要格外注意,不是託管態,是離開Session管理的狀態。處於脫管態的持久化物件的識別符號屬性和資料庫表中某條記錄的主鍵對應,但是它脫離了Session的管理,再次對其操作時,Hibernate無法感知其變化。如下示例:
Java程式碼
雖然後來又修改了user物件的city屬性,但是是在脫管態修改的,程式結束也不能再影響資料庫中資料變化。處於脫管態的物件可以重新呼叫Session物件的update()方法回到持久態,否則Java虛擬機器會在適當時間進行垃圾收集。重新持久化物件的過程如下:
Java程式碼
當使用Session物件的delete()方法刪除資料後,處於持久態的物件失去和資料庫資料的對應關係,此時的持久化物件將在適當時間被Java虛擬機器進行垃圾收集。
Java程式碼
至此Hibernate中持久化物件的三種狀態介紹完了。我們會發現處於瞬時態和脫管態的物件不在Hibernate的Session管理中,這時無論怎樣修改物件的屬性都不會影響資料庫中的資料。而處於持久態的物件在Session物件執行close()方法或Transaction物件執行commit()方法時,資料庫中資料會同步更新,這也是Hibernate對物件的“髒”資料進行檢查的一種方式。
持久化物件的生命週期有三種,分別是瞬時態(Transient),持久態(Persistent)和脫管態(Detached)。
瞬時態的物件是剛剛用new關鍵字創建出來的,還沒有進入Session,此時的物件沒有和資料庫中的記錄對應。示例程式碼如下:
Java程式碼
- User user = new User();
- user.setName("Sarin");
- user.setCity("大連");
- user.setDepartment("研發部");
- user.setPhone("15912345678");
- user.setHireTime(new
這時user就是出於瞬時態的持久化物件。
通過Session物件的save(),persist()或者saveOrUpdate()方法進行儲存處於瞬時態的物件後,該物件就變為持久態。此時Session中已經存在該物件,並且對應資料庫中的一條記錄。值得注意的是在Session物件失效之前,對持久態物件的任何修改,在呼叫Session物件的close()方法或者Transaction物件的commit()方法之後,資料庫表中對應的資料會同時更新。示例程式碼如下:
Java程式碼
- SessionFactory sessionFactory = config.buildSessionFactory();
- Session session = sessionFactory.getCurrentSession();
- Transaction tx = session.beginTransaction();
- User user = new User();
- user.setName("Sarin");
- user.setCity("大連");
- user.setDepartment("研發部");
- user.setPhone("15912345678");
- user.setHireTime(new java.util.Date());
- session.save(user);
- tx.commit();
在呼叫save()方法後,持久化物件user就變為持久態,但是執行了commit()方法之後,資料庫操作才會進行,這點必須明確。所以在資料庫操作執行之前對持久化物件的修改Hibernate可以感知。
而且Session物件的get()和load()方法也可以返回一個持久態的物件,這個物件代表資料庫表中的一條記錄。
脫管態,這個要格外注意,不是託管態,是離開Session管理的狀態。處於脫管態的持久化物件的識別符號屬性和資料庫表中某條記錄的主鍵對應,但是它脫離了Session的管理,再次對其操作時,Hibernate無法感知其變化。如下示例:
Java程式碼
- SessionFactory sessionFactory = config.buildSessionFactory();
- Session session = sessionFactory.getCurrentSession();
- Transaction tx = session.beginTransaction();
- User user = new User();
- user.setName("Sarin");
- user.setCity("大連");
- user.setDepartment("研發部");
- user.setPhone("15912345678");
- user.setHireTime(new java.util.Date());
- session.save(user);
- tx.commit();
- user.setCity("北京");
雖然後來又修改了user物件的city屬性,但是是在脫管態修改的,程式結束也不能再影響資料庫中資料變化。處於脫管態的物件可以重新呼叫Session物件的update()方法回到持久態,否則Java虛擬機器會在適當時間進行垃圾收集。重新持久化物件的過程如下:
Java程式碼
- SessionFactory sessionFactory = config.buildSessionFactory();
- Session session = sessionFactory.getCurrentSession();
- Transaction tx = session.beginTransaction();
- User user = new User();
- user.setName("Sarin");
- user.setCity("大連");
- user.setDepartment("研發部");
- user.setPhone("15912345678");
- user.setHireTime(new java.util.Date());
- session.save(user);
- tx.commit();
- user.setCity("北京");
- session = sessionFactory.getCurrentSession();
- tx = session.beginTransaction();
- session.update(user);
- tx.commit();
當使用Session物件的delete()方法刪除資料後,處於持久態的物件失去和資料庫資料的對應關係,此時的持久化物件將在適當時間被Java虛擬機器進行垃圾收集。
Java程式碼
- SessionFactory sessionFactory = config.buildSessionFactory();
- Session session = sessionFactory.getCurrentSession();
- Transaction tx = session.beginTransaction();
- User user = (User) session.get(User.class, new Integer(1));
- session.delete(user);
- tx.commit();
至此Hibernate中持久化物件的三種狀態介紹完了。我們會發現處於瞬時態和脫管態的物件不在Hibernate的Session管理中,這時無論怎樣修改物件的屬性都不會影響資料庫中的資料。而處於持久態的物件在Session物件執行close()方法或Transaction物件執行commit()方法時,資料庫中資料會同步更新,這也是Hibernate對物件的“髒”資料進行檢查的一種方式。