在向數(shù)據(jù)庫(kù)中增加一條新的條目時(shí),發(fā)現(xiàn)如果文字(有英文字母,也有漢字)數(shù)量特別大,超過1000個(gè),則每次通過Hibernate,向一個(gè)String類型的字段中增加數(shù)據(jù)時(shí),只有幾百個(gè)字可以增加進(jìn)去,其他的自動(dòng)丟失了。
答:這是由于字段長(zhǎng)度設(shè)置不合理造成的??梢愿鶕?jù)字符串實(shí)際長(zhǎng)度考慮使用Text、LongText、或者Blob等字段類型。不同數(shù)據(jù)庫(kù)的字段類型稍有不同,可以參考相關(guān)手冊(cè)。另外需要注意的是一個(gè)漢字占用兩個(gè)字節(jié)長(zhǎng)度。
12問:為什么采用Hibernate的批量刪除方法來刪除大批量的記錄數(shù)據(jù)時(shí)速度特別慢
答:在使用Hibernate版本2.X時(shí),不推薦采用Hibernate的批量刪除方法來刪除大量記錄。原因是,Hibernate會(huì)執(zhí)行1條查詢語(yǔ)句,另外還有滿足條件的多條刪除語(yǔ)句,而不是一次執(zhí)行一個(gè)刪除語(yǔ)句,所以當(dāng)待刪除的數(shù)據(jù)很多時(shí),會(huì)有很大的性能瓶頸。而對(duì)于Hibernate 3.0以上的版本,則不存這個(gè)問題。
13問:升級(jí)Hibernate 3后在導(dǎo)入hbm映射文件時(shí)為什么非常非常慢
原先在Hibernate 2中,程序的速度是非??斓摹.?dāng)環(huán)境順利從Hibernate 2升級(jí)到Hibernate 3后,發(fā)布時(shí)在Tomcat的控制臺(tái)中發(fā)現(xiàn):Hibernate 3裝載hbm映射文件時(shí)非常慢,差不多10秒鐘才能裝載一個(gè)hbm文件。
答:通過在Hibernate的源代碼中設(shè)置斷點(diǎn),可以發(fā)現(xiàn)執(zhí)行效率低下的代碼在org.hibernate.cfg.Configuration文件中的第240行:
addInputStream( new FileInputStream( xmlFile ) );
而addInputStream函數(shù)中又包含:
org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver ).read( new InputSource( xmlInputStream ) );
跟蹤org.hibernate.util.XMLHelper中的函數(shù)createSAXReader可以得出結(jié)論,問題的癥結(jié)出在這一條語(yǔ)句:
org.dom4j.Document doc = xmlHelper.createSAXReader()
可以判斷這是在XML文件裝載初始化時(shí)發(fā)生的錯(cuò)誤,仔細(xì)檢查XML文件,可以發(fā)現(xiàn)這是XML的第一行聲明dtd的錯(cuò)誤,因?yàn)橐郧笆褂玫氖荋ibernate 2,所以hbm文件的dtd指向的是版本2,而升級(jí)Hibernate 3后,沒有把老的hbm映射文件換成版本3。在更換為3版本后,此問題得到解決。
14問:為什么Hibernate 3中的HQL無(wú)法查詢漢字
使用同樣的代碼和配置文件,在Hibernate 2上完全沒有問題,在Hibernate 3中,使用如下HQL查詢,無(wú)法得到正確的結(jié)果集:
String hql = "from story where title like '%漢字%'";
Query q = session.createQuery(hql);
但用下面的HQL查詢,卻可以得到正確結(jié)果集:
String hql = " from story where title like '%english%'";
Query q = session.createQuery(hql);
答:如果采用的是拼接HQL的方式,從Hibernate 2升級(jí)到Hibernate 3確實(shí)會(huì)出現(xiàn)漢字亂碼問題。在控制臺(tái)中可以看到,SQL的漢字部分變成了亂碼:
[DEBUG] 2005-08-14 14:33:58 org.hibernate.SQL - "select story0_.content from story as story0_ where story0_.title like '%&–°é—&&`¨&'
在Hibernate中,查詢時(shí)應(yīng)盡量使用占位符的寫法(如下),這樣既可以避免亂碼問題,又可以避免潛在的SQL注入攻擊:
getHibernate().find("from story where title like ? ", "%漢字%")
15問:Hibernate 3中如何獲得庫(kù)表所有字段的名稱
答:可以使用以下的程序獲得。
Configuration conf = new Configuration();
16問:錯(cuò)誤代碼:ObjectNotFoundException: No row with the given identifier exists
答:在以下幾種情況下,該錯(cuò)誤可能會(huì)發(fā)生。
檢查裝載使用的主鍵Id,并驗(yàn)證外鍵關(guān)系,以確定數(shù)據(jù)庫(kù)中已經(jīng)存在相應(yīng)的約束關(guān)系。堅(jiān)持“在一個(gè)Session中只處理一個(gè)事務(wù)”的原則。因?yàn)楫?dāng)在單一Session中使用多個(gè)事務(wù)時(shí)很容易犯錯(cuò)。尤其注意,在一個(gè)HibernateException已經(jīng)拋出后不要再操作Session。
17問:錯(cuò)誤代碼:InvalidObjectException: Could not find a SessionFactory named: null
答:這個(gè)錯(cuò)誤在以下幾種情況下經(jīng)常發(fā)生。
18問:錯(cuò)誤代碼:org.hibernate.HibernateException: CGLIB Enhancement failed: <classname>
答:Hibernate 3的默認(rèn)方式是把所有類通過代理方式來進(jìn)行延遲加載。如果代碼中的類有一個(gè)私有無(wú)參的構(gòu)造器的話,Hibernate將無(wú)法在運(yùn)行時(shí)將項(xiàng)目代碼中的類作為子類裝載。為了避免這個(gè)錯(cuò)誤,類中的構(gòu)造器函數(shù)至少應(yīng)該在包內(nèi)可見。
19問:為什么在Hibernate中添加、刪除、修改一個(gè)對(duì)象或Collection,但是數(shù)據(jù)庫(kù)中實(shí)際上沒有任何變化
答:這個(gè)問題經(jīng)常會(huì)困擾初學(xué)者。這是因?yàn)槿绻麤]有使用Hibernate的自動(dòng)事務(wù)處理,則必需顯式的提交事務(wù),操作才會(huì)在數(shù)據(jù)庫(kù)中執(zhí)行。
20問:為什么保存一個(gè)父對(duì)象,而它的關(guān)聯(lián)對(duì)象沒有自動(dòng)儲(chǔ)存到數(shù)據(jù)庫(kù)里
答:關(guān)聯(lián)對(duì)象必需顯式的調(diào)用session.save()(或session.persist()),或者在關(guān)聯(lián)的映射文件中加入cascade="all"或cascade="save-update"(或cascade="persist")才能夠自動(dòng)關(guān)聯(lián)執(zhí)行。
聯(lián)系客服