小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Hibernate 實(shí)體對象的識別

 feimishiwo 2014-04-29
 
實(shí)體對象的識別:
   在基本的Java編程中,對象的識別也是一個(gè)必須要面對的問題,在Java中可以通過”==”運(yùn)算符來判斷兩個(gè)對象是否具有相同的引用,還可以通過從根類Object繼承而來的”equals()”方法,來判斷兩個(gè)對象的值是否相等?;谶@兩個(gè)Java提供的工具,我們可以輕松的判斷兩個(gè)對象的差別,但是在面對持久化邏輯時(shí),這兩個(gè)工具就遇到了它愛莫能助的新問題,比如我們現(xiàn)在有兩個(gè)實(shí)體類,一個(gè)代表用戶我們稱為User,另一個(gè)代表用戶的地址我們稱為Address,并且UserAddress是一對多的關(guān)聯(lián)關(guān)系。
我們看以下代碼:
User user1=session.load(User.class,”1”);
user1.setAge(“27”);
User user2=session.load(User.class,”1”);
依照基本的Java編程規(guī)則user1user2無論是引用還是值都不相同,但是user1user2在數(shù)據(jù)庫中確實(shí)是代表同一條記錄,因此他們其實(shí)具備等價(jià)關(guān)系。怎樣才能準(zhǔn)確的確定實(shí)體對象的身份?站在數(shù)據(jù)庫的角度,一條記錄可以由主鍵來唯一確定,所以我們可以這樣作出約定,只要兩個(gè)實(shí)體的主鍵值相等,那么這兩個(gè)實(shí)體對象就代表同一個(gè)實(shí)體對象。
  Hibernate而言,這個(gè)規(guī)則一樣成立,在Hibernate中,net.sf.hibernate.engine.Key(在Hibernate3中是org.hibernate.engine.Key類)類封裝了用于區(qū)別兩個(gè)實(shí)體的信息。在這個(gè)類中,主要有三個(gè)信息,分別是實(shí)體對象的Class對象,實(shí)體類的名稱,實(shí)體ID,通過ID Hibernate就可以將代表不同記錄數(shù)據(jù)的實(shí)體對象區(qū)分開。另外Key類還有作為實(shí)體對象在緩存中標(biāo)識的作用,Hibernate會根據(jù)Key在緩存中尋找是否有對應(yīng)的實(shí)體對象。所以在實(shí)際開發(fā)中,當(dāng)我們使用一些自動(dòng)生成實(shí)體類的工具時(shí),這些工具都會為我們自動(dòng)生成,這個(gè)實(shí)體類的equals()方法和hashCode()方法,來實(shí)現(xiàn)上述規(guī)則,以便能夠在實(shí)體對象比較時(shí),自動(dòng)區(qū)分不同的實(shí)體對象,比如User類會生成如下的equals()hashCode()方法:
public boolean equals(Object other){
 if(this==other) return true;
 if(!other instanceof User) return false;
 User castother=(User)other;
 return new EqualsBuilder().append(this.getId(),castother.getId()).isEquals();
}
public int hashCode(){
 return new HashCodeBuilder().append(getId()).toHashCode();
}
以上的代碼實(shí)現(xiàn)了我們約定的邏輯,當(dāng)兩個(gè)實(shí)體主鍵相同時(shí),我們就認(rèn)為這兩個(gè)實(shí)體表示的是兩個(gè)相同的實(shí)體對象。
這種處理在通常情況下是不會出問題的,在我們平常的開發(fā)中也很少遇到問題,但是很少并不代表沒有問題,我們來看下面的代碼:
User user=(User)session.load(User.class,”1”);
Iterator it=user.getAddress().iterator();
Address addr=(Address)it.next();
 
User user2=(User)session2.load(User.class,”1”);
Iterator it2=user2.getAddress().iterator();
user2.getAddress().add(addr);
Transaction trans=session.beginTransaction();
session2.save(user2);
session.commit();
這段代碼在執(zhí)行時(shí),會拋出NonUniqueObjectException異常,為什么會這樣?這是因?yàn)?,我們將從第一個(gè)Session中加載的Address對象,放入了由第二個(gè)Session所加載的同一個(gè)User對象的Set集合中,這時(shí)我們上述的規(guī)則將會失效,因?yàn)檫@個(gè)規(guī)則無法支持實(shí)體的跨Session識別。這種情況在實(shí)際開發(fā)中比較少見,但是作為合格開發(fā)人員,應(yīng)該清楚這個(gè)情況的存在。如果在開發(fā)中真的出現(xiàn)這種情況時(shí),該怎么辦呢?這時(shí)我們就要通過值比對來覆蓋equals()/hashCode()方法,所謂值比對就是就是將實(shí)體中所有的屬性,挨個(gè)進(jìn)行值比較和生成hash碼,只要有一個(gè)屬性不相同,我們就認(rèn)為這兩個(gè)實(shí)體是不同的兩個(gè)實(shí)體。有時(shí)候值比對方法,還會用在有業(yè)務(wù)主鍵的時(shí)候,比如說如果兩個(gè)User的名字相同,那么這兩個(gè)實(shí)體就相同,這時(shí)屬性Name就是業(yè)務(wù)主鍵,這時(shí)必須在User實(shí)體類的equals()方法實(shí)現(xiàn)對名字的值比較,并且針對Name生成Hash碼。
注意:通常業(yè)務(wù)主鍵是由業(yè)務(wù)邏輯決定的。
 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多