在用Hibernate的時(shí)候,時(shí)不時(shí)會(huì)因?yàn)闆](méi)有處理好實(shí)體對(duì)象的狀態(tài)而犯一些莫名其妙的異常,在這里對(duì)實(shí)體對(duì)象的各種狀態(tài)整理一下,希望能有所幫助。
Hibernate實(shí)體對(duì)象,即指Hibernate O/R影射關(guān)系中的域?qū)ο?即O/R中的"O"。在Hibrenate實(shí)體對(duì)象的生命周期中存在著三中狀態(tài),即:
1:自由狀態(tài)(Transient)。
2:持久狀態(tài)(Persistent)。
3:游離狀態(tài)(Detached)。
1:自由狀態(tài)(Transient)
自由狀態(tài)(Transient),是指實(shí)體對(duì)象在內(nèi)存中自由存在,他與數(shù)據(jù)庫(kù)的記錄無(wú)關(guān)。如:
- TUser user = new TUser();
- user.setName("MyName");
TUser user = new TUser();
user.setName("MyName");
這里的user對(duì)象只是一個(gè)非常普通的java對(duì)象,與數(shù)據(jù)庫(kù)中的記錄沒(méi)有任何關(guān)系。
2:持久狀態(tài)(Persistent)
持久狀態(tài)(Persistent),即實(shí)體對(duì)象處于Hibernate框架的管理狀態(tài),實(shí)體對(duì)象被納入Hibernate的實(shí)體容器中管理。處于
持久狀態(tài)的對(duì)象,其更變將由Hibernate固化到數(shù)據(jù)庫(kù)中。如:
-
- 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();
-
-
//創(chuàng)建兩個(gè)處于自由狀態(tài)的實(shí)體對(duì)象。
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);
//通過(guò)session的save方法,user_1對(duì)象已經(jīng)被納入Hibernate的實(shí)體管理容器,處于持久化狀
//態(tài)(Persistent),這時(shí)候?qū)ser_1對(duì)象的任何修改都將被同步到數(shù)據(jù)庫(kù)中。
tx.commit();
//而user_2仍然才處于自由狀態(tài)(Transient),不受Hibernate框架的管理。
從上面看到,處于
自由狀態(tài)的實(shí)體對(duì)象,可以通過(guò)Hibernate的Session.sava方法轉(zhuǎn)化為
持久狀態(tài)。
除了用Session.save方法外,還可以通過(guò)其他方法來(lái)獲取一個(gè)
持久狀態(tài)的對(duì)象,那就是直接通過(guò)Hibernate加載的對(duì)象,通過(guò)Session.load方法,可以直接加載一個(gè)處于
持久狀態(tài)的實(shí)體對(duì)象。如下:
- TUser user = Session.load(TUser.class,new Integer(1));
-
-
TUser user = Session.load(TUser.class,new Integer(1));
//在load方法沒(méi)返回之前,就已經(jīng)先把對(duì)象納入Hibernate的管理范圍,所以這里的user
//已經(jīng)處于持久狀態(tài)。
從上面的代碼可以看出,處于
持久狀態(tài)的實(shí)體對(duì)象一定要和Session關(guān)聯(lián),并處于該Session的有效期內(nèi)。
3:游離狀態(tài)(Detached)
處于
持久狀態(tài)的實(shí)體對(duì)象,在其關(guān)聯(lián)的Session關(guān)閉以后,此實(shí)體對(duì)象就處于
游離狀態(tài),
- 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);//把自由狀態(tài)的實(shí)體對(duì)象user轉(zhuǎn)為持久狀態(tài),
tx.commit();
session.close();
//session關(guān)閉以后,處于持久狀態(tài)的實(shí)體對(duì)象user將轉(zhuǎn)為游離狀態(tài)。
//因?yàn)榇藭r(shí)user已經(jīng)和session脫離關(guān)系。
由上面可以看到實(shí)體對(duì)象的
游離狀態(tài)是在對(duì)象和它所寄宿的Session脫離關(guān)系后形成的,但處于
自由狀態(tài)的實(shí)體對(duì)象也沒(méi)有和任何session有關(guān)聯(lián),那么他們兩者有什么區(qū)別呢?關(guān)鍵的就在我們對(duì)
自由狀態(tài)的實(shí)體對(duì)象執(zhí)行了Session.save方法,
當(dāng)我們執(zhí)行
- TUser user = new TUser();
TUser user = new TUser();
時(shí),我們只是創(chuàng)建了一個(gè)普通的對(duì)象,他并沒(méi)有和數(shù)據(jù)庫(kù)里的任何一條記錄對(duì)應(yīng),當(dāng)我們執(zhí)行
Session.save以后,Hibernate就為user設(shè)置了一個(gè)主鍵,就是user.Id屬性,通過(guò)這個(gè)屬性,Hibernate就把user對(duì)象和數(shù)據(jù)庫(kù)里的記錄關(guān)聯(lián)起來(lái),所以
自由狀態(tài)和
游離狀態(tài)的基本區(qū)別就是 處于
游離狀態(tài)的實(shí)體對(duì)象,在數(shù)據(jù)庫(kù)里有對(duì)應(yīng)的記錄,因此它可以通過(guò)和session關(guān)聯(lián)再次轉(zhuǎn)為
持久狀態(tài)。
三種狀態(tài)的轉(zhuǎn)化
自由狀態(tài)-->持久狀態(tài):可以通過(guò)Session.sava方法來(lái)轉(zhuǎn)換。
持久狀態(tài)-->游離狀態(tài):可以通過(guò)Session.close方法來(lái)關(guān)閉session,獲取游離狀態(tài)的對(duì)象
持久狀態(tài)-->自由狀態(tài):可以通過(guò)Session.delete方法來(lái)刪除實(shí)體對(duì)象對(duì)應(yīng)的數(shù)據(jù)庫(kù)記錄,使實(shí)體對(duì)象處于自由狀態(tài)。
補(bǔ)充一下,有時(shí)可能會(huì)想,可以通過(guò)認(rèn)為的個(gè)處于
自由狀態(tài)的實(shí)體對(duì)象設(shè)置一個(gè)Id值
user.Id=1
,來(lái)人為的創(chuàng)建一個(gè)
游離狀態(tài)的對(duì)象。
這里注意一點(diǎn),我們可以人為地給實(shí)體對(duì)象設(shè)置Id值,我我們無(wú)法知道這個(gè)ID值在數(shù)據(jù)庫(kù)里有沒(méi)有對(duì)應(yīng)的記錄,如果沒(méi)有,就算我們?nèi)藶榈卦O(shè)置了Id,也不能說(shuō)一個(gè)有ID的實(shí)體對(duì)象就是一個(gè)
游離狀態(tài)的對(duì)象。