收集:Hibernate中常見問題 No row with the given identifi.docx_第1頁
收集:Hibernate中常見問題 No row with the given identifi.docx_第2頁
收集:Hibernate中常見問題 No row with the given identifi.docx_第3頁
收集:Hibernate中常見問題 No row with the given identifi.docx_第4頁
收集:Hibernate中常見問題 No row with the given identifi.docx_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Hibernate中常見問題 No row with the given identifier exists問題的原因及解決產(chǎn)生此問題的原因:有兩張表,table1和table2. 產(chǎn)生此問題的原因就是table1里做了關(guān)聯(lián)或者(特殊的多對(duì)一映射,實(shí)際就是一對(duì)一)來關(guān)聯(lián)table2.當(dāng)hibernate查找的時(shí)候,table2里的數(shù)據(jù)沒 有與table1相匹配的,這樣就會(huì)報(bào)No row with the given identifier exists這個(gè)錯(cuò).(一句話,就是數(shù)據(jù)的問題!)假如說,table1里有自身的主鍵id1,還有table2的主鍵id2,這兩個(gè)字段.如果hibenrate設(shè)置的單項(xiàng)關(guān)聯(lián),即使table1中的id2為null值,table2中id2中有值,查詢都不會(huì)出錯(cuò).但是如果table1中的id2字段有值,但是這個(gè)值在table2中主鍵值里并沒有,就會(huì)報(bào)上面的錯(cuò)!如果hibernate是雙向關(guān)聯(lián),那么table1中的id2為null值,但是table2中如果有值,就會(huì)報(bào)這個(gè)錯(cuò).這種情況目前的解決辦法就是改成單項(xiàng)關(guān)聯(lián),或者把不對(duì)應(yīng)的數(shù)據(jù)改對(duì)!這就是報(bào)這個(gè)錯(cuò)的原因了,知道原因了就相應(yīng)的改就行了.或許還有些人迷惑hibernate關(guān)聯(lián)都配好了,怎么會(huì)出現(xiàn)這樣的錯(cuò)?其實(shí)這是編程的時(shí)候出現(xiàn)的 問題,假如說我在添加信息的時(shí)候,頁面?zhèn)鬟^來的struts的formbean到dao方法中需要封裝成hibernate的po(就是 hibenrate的bean),要是一個(gè)個(gè)po.get(form.set()實(shí)在太麻煩了,這樣一般都會(huì)寫個(gè)專門的方法來封裝,遇到 po.get(form.set()這種情況直接把struts的formbean對(duì)象傳到此方法中封裝就行了,假如我有個(gè)字段是創(chuàng)建人id,那么這個(gè) 字段是永遠(yuǎn)不會(huì)改的,我在添加的時(shí)候還調(diào)用這個(gè)方法,這個(gè)專門封裝的方法是有一些判斷的,假如說我判斷一下,如果遇到創(chuàng)建人id傳過來為空值,我判斷如果 是空值,我把創(chuàng)建人id設(shè)為0,但是用戶表中userid是主鍵從1開始自增的,那么這樣數(shù)據(jù)就對(duì)應(yīng)不上了,一查就會(huì)出這個(gè)錯(cuò)了.這個(gè)錯(cuò)在開發(fā)剛開始的時(shí) 候經(jīng)常發(fā)生,因?yàn)槊總€(gè)人的模塊都是由相應(yīng)的人獨(dú)立開發(fā)完成以后再整合在一起的,每個(gè)人寫單獨(dú)那一塊的時(shí)候往往會(huì)忽略這些,所以整合的時(shí)候這些問題往往就都 一下子全冒出來了.整合很辛苦,tnnd!hibernate的查詢的比較hibernate的查詢有很多,Query,find,Criteria,get,loadquery使用hsql語句,可以設(shè)置參數(shù)是常用的一種方式criteria的方式,盡量避免了寫hql語句,看起來更面向?qū)ο罅?。find方式,這種方式已經(jīng)被新的hibernate丟棄get和load方式是根據(jù)id取得一個(gè)記錄下邊詳細(xì)說一下get和load的不同,因?yàn)橛行r(shí)候?yàn)榱藢?duì)比也會(huì)把find加進(jìn)來。1,從返回結(jié)果上對(duì)比:load方式檢索不到的話會(huì)拋出org.hibernate.ObjectNotFoundException異常get方法檢索不到的話會(huì)返回null2,從檢索執(zhí)行機(jī)制上對(duì)比:get方法和find方法都是直接從數(shù)據(jù)庫中檢索而load方法的執(zhí)行則比較復(fù)雜1,首先查找session的persistent Context中是否有緩存,如果有則直接返回2,如果沒有則判斷是否是lazy,如果不是直接訪問數(shù)據(jù)庫檢索,查到記錄返回,查不到拋出異常3,如果是lazy則需要建立代理對(duì)象,對(duì)象的initialized屬性為false,target屬性為null4, 在訪問獲得的代理對(duì)象的屬性時(shí),檢索數(shù)據(jù)庫,如果找到記錄則把該記錄的對(duì)象復(fù)制到代理對(duì)象的target上,并將initialized=true,如果找不到就拋出異常 。java.lang.IllegalArgumentException: node to traverse cannot be null!錯(cuò)誤原因: 通常此類錯(cuò)誤都是由于HQL語句寫的不正確,例如from寫成了form,或者set A = 1 and B = 2,其中set不同字段用逗號(hào),分離而不是用and.總之仔細(xì)檢查HQL語句,看看有沒有語法錯(cuò)誤即可.ids for this class must be manually assigned before calling save().org.hibernate.id.IdentifierGenerationException:idsforthisclassmustbemanuallyassignedbeforecallingsave():引起問題的原因:由Hibernate根據(jù)數(shù)據(jù)庫表自動(dòng)生成的類名.hbm.xml映射文件引起的。首先我的表(Info)由兩個(gè)字段組成,即:int id;/主建String name;(自己做測(cè)試,所以就簡單的建了個(gè)表)由Hibernate生成的Info.hbm.xml中是這樣寫的:- -這個(gè)是必須有的。它是用來定義實(shí)體的標(biāo)識(shí)屬性(對(duì)應(yīng)數(shù)據(jù)庫表的主鍵)而我這里由于id本身就是主鍵,所以column的屬性便是id下面是很關(guān)鍵的一點(diǎn),由于一時(shí)興趣,于是找了很多資料,關(guān)于它的解釋是:用于指定主鍵的生成策略。它的值有多,下面是轉(zhuǎn)來的:-“assigned”主鍵由外部程序負(fù)責(zé)生成,在 save() 之前指定一個(gè)。“hilo”通過hi/lo 算法實(shí)現(xiàn)的主鍵生成機(jī)制,需要額外的數(shù)據(jù)庫表或字段提供高位值來源?!皊eqhilo”與hilo 類似,通過hi/lo 算法實(shí)現(xiàn)的主鍵生成機(jī)制,需要數(shù)據(jù)庫中的 Sequence,適用于支持 Sequence 的數(shù)據(jù)庫,如Oracle?!癷ncrement”主鍵按數(shù)值順序遞增。此方式的實(shí)現(xiàn)機(jī)制為在當(dāng)前應(yīng)用實(shí)例中維持一個(gè)變量,以保存著當(dāng)前的最大值,之后每次需要生成主鍵的時(shí)候?qū)⒋酥导?作為主鍵。這種方式可能產(chǎn)生的問題是:不能在集群下使用。“identity”采用數(shù)據(jù)庫提供的主鍵生成機(jī)制。如DB2、SQL Server、MySQL 中的主鍵生成機(jī)制?!皊equence”采用數(shù)據(jù)庫提供的 sequence 機(jī)制生成主鍵。如 Oralce 中的Sequence?!皀ative”由 Hibernate 根據(jù)使用的數(shù)據(jù)庫自行判斷采用 identity、hilo、sequence 其中一種作為主鍵生成方式?!皍uid.hex”由 Hibernate 基于128 位 UUID 算法 生成16 進(jìn)制數(shù)值(編碼后以長度32 的字符串表示)作為主鍵?!皍uid.string”與uuid.hex 類似,只是生成的主鍵未進(jìn)行編碼(長度16),不能應(yīng)用在 PostgreSQL 數(shù)據(jù)庫中?!癴oreign”使用另外一個(gè)相關(guān)聯(lián)的對(duì)象的標(biāo)識(shí)符作為主鍵。-看了上面的介紹,再看看代碼,原來是屬性設(shè)置有問題。然后改為identity、native問題便解決。使用Hibernate設(shè)計(jì)Dao層的幾種方式 直接奔主題,說一說數(shù)據(jù)庫訪問層的問題,該層操作數(shù)據(jù)庫的實(shí)現(xiàn)方式有很多種,當(dāng)然各有各的好處,選擇哪一種,根據(jù)你的心情而定,dao層所做的事情就是單純的數(shù)據(jù)CRUD,不做別的事情,如果你發(fā)現(xiàn)你的dao層存在業(yè)務(wù)邏輯,那么趕緊在項(xiàng)目沒有做大之前改掉吧,因?yàn)槲揖驮窨吹竭^我以為同學(xué),把DAO層和Service層搞混了,dao存在于大多數(shù)軟件工程中,它已成為程序架構(gòu)必不可少的組成部分,當(dāng)然,dao是可拔插的,如果你的dao寫死在了某個(gè)程序里,那說明你對(duì)于dao的理解并不透徹,試著把你的dao移植到別的程序里吧,如果不能做到“一次編寫,到處運(yùn)行”,那就考慮重構(gòu)你的dao層吧!第一種:直接寫JDBC來實(shí)現(xiàn)數(shù)據(jù)庫的操作,這種方式是最原始的,當(dāng)然,如果你對(duì)于寫JDBC非常的熟悉,那沒問題,但是這并不是一個(gè)追求上進(jìn)的程序員做的事,久而久之,這將是一件痛苦的事,而不是一件值得炫耀的事那么以下的幾種方法就是直接通過或間接通過hibernate框架來實(shí)現(xiàn)dao層的設(shè)計(jì)了,因?yàn)閔ibernate夠強(qiáng)大,夠流行,夠靈活,曾經(jīng)試過使用JBoss寫DAO,的確不怎么爽!第二種:使用hibernate的session實(shí)現(xiàn)數(shù)據(jù)庫操作,這種方式是使用hibernate的最基礎(chǔ)的方式,也是最靈活的一種方式,因?yàn)閟ession實(shí)現(xiàn)了hibernate的所有數(shù)據(jù)庫操作方法,剩下的就看你如何組裝這些語句完成你的程序邏輯了第三種:繼承Spring的HibernateDaoSupport,Spring為Hibernate的Dao提供的工具類,其底層是通過HibernateTemplate來實(shí)現(xiàn)數(shù)據(jù)庫的操作,但是使用這個(gè)工具類,有些地方,對(duì)于數(shù)據(jù)庫的操作并不夠靈活,曾經(jīng)我為了這些問題糾結(jié)了很久,也許是我個(gè)人對(duì)這個(gè)類的熟悉度有限,如果有哪位童鞋能靈活的運(yùn)用此類,還望指點(diǎn)一二第四種:使用HibernateTemplate,它提供了非常多的常用方法來完成數(shù)據(jù)庫的基本操作,使得持久層訪問摸板化,這種方式其實(shí)和第三種差不多,不多做解釋,但是要靈活的運(yùn)用該模板,還得知道第五種方式第五種:Hibernate的復(fù)雜用法HibernateCallback回調(diào)函數(shù),通過調(diào)用回調(diào)函數(shù)來實(shí)現(xiàn)的數(shù)據(jù)庫操作,這種方式可以完全使用Hibernate的 session操作數(shù)據(jù)庫,這也是我最喜歡用的方法,因?yàn)樗鼔驈?qiáng)大,夠靈活,夠高深第六種:使用EntityManager,EntityManager里也封裝了hibernate對(duì)數(shù)據(jù)庫的操作,可以通過PersistenceContext注解為其注入實(shí)例,但是本人對(duì)于此類的使用方法并不是很熟悉,也只使用過一次而已,還在學(xué)習(xí)中以上只是列舉了我使用過的DAO層的設(shè)計(jì)方案,并沒有提供具體的實(shí)現(xiàn)代碼,這里寫代碼的確不方便,以上的六種實(shí)現(xiàn)方式,都有各的好處,也遇到過一些細(xì)節(jié)上的問題,只有經(jīng)過更多的人的使用,才可以找到問題,并且去解決問題,對(duì)于有意了解使用以上幾種方式的詳情的童鞋,可以一起討論討論,并提供你的實(shí)現(xiàn)源碼!如何打破多表關(guān)聯(lián)的關(guān)系在多表關(guān)聯(lián)的關(guān)系中,如果要?jiǎng)h除其中一個(gè)表中的一條子數(shù)據(jù),必定與這個(gè)表,這條數(shù)據(jù)有關(guān)聯(lián)的數(shù)據(jù)也會(huì)被刪除,但是這樣的結(jié)果卻不是我們要見到的。而我們要的效果是,1.刪除子數(shù)據(jù),父數(shù)據(jù)不被刪除,與關(guān)聯(lián)的表也不刪除。2.刪除父數(shù)據(jù),而父數(shù)據(jù)下的子數(shù)據(jù),孫子數(shù)據(jù)也會(huì)被刪除,而與它關(guān)聯(lián)的表也不刪除。而怎樣實(shí)現(xiàn)這樣的結(jié)果呢,這就需要我們?nèi)ゴ蚱扑麄冎g的關(guān)系了。怎么打破呢,看下面的代碼。-這是一個(gè)個(gè)人空間中說說表say的刪除代碼-發(fā)表一條說說,要知道發(fā)表說說的人,和回復(fù)說說的人,而這倆者都是一個(gè)user表里面的。所以說,這個(gè)說說表say是跟用戶表user是關(guān)聯(lián)的,用戶表跟說說表是一對(duì)多的關(guān)系。 -刪除父說說-Transactionalpublic boolean deleteFatherSay(Integer sayId) Say say = sayDao.findById(sayId); /獲取父節(jié)點(diǎn)Iterator iter = say.getSays().iterator(); /獲取父節(jié)點(diǎn)下的子節(jié)點(diǎn),并存在迭代器里面for (int i = 0; i say.getSays().size(); i+) /循環(huán)遍歷每個(gè)子節(jié)點(diǎn)Say say1 = iter.next(); /獲取單個(gè)的子節(jié)點(diǎn)Iterator iter1 = say1.getSays().iterator(); /獲取單個(gè)子節(jié)點(diǎn)下孫子節(jié)點(diǎn),并存在迭代器里面for (int j = 0; j say1.getSays().size(); j+) /循環(huán)遍歷每個(gè)孫子節(jié)點(diǎn)Say say2 = iter1.next(); /獲取單個(gè)的孫子節(jié)點(diǎn)say2.setUser(null); /打破孫子節(jié)點(diǎn)與user的關(guān)聯(lián)say2.setSay(null); /打破孫子節(jié)點(diǎn)與子節(jié)點(diǎn)的關(guān)系(刪除孫子節(jié)點(diǎn)時(shí),就不會(huì)把與孫子節(jié)點(diǎn)相關(guān)聯(lián)的子節(jié)點(diǎn)也刪除)sayDao.delete(say2);say1.setSay(null);say1.setUser(null);sayDao.delete(say1);say.setUser(null);sayDao.delete(say);return true; -刪除子說說-Transactionalpublic boolean deleteSonSay(Integer sayId) Say say = new Say();say.setSayId(sayId);String hql = from Say as say1 where say1.say= + sayId;List list = sayDao.findByHql(hql);Iterator iter = list.iterator();for (int i = 0; i list.size(); i+) Say say1 = iter.next();say1.setUser(null);say1.setSay(null);sayDao.delete(say1);say.setSay(null);say.setUser(null);say.setSays(null);sayDao.delete(say);return true; -刪除孫子說說-Transactionalpublic boolean deleteGrandsonSay(Integer sayId) Say say = sayDao.fin

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論