在用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的實體對象就是一個
游離狀態的對象。