當(dāng)我們從數(shù)據(jù)庫(kù)得到一個(gè)對(duì)象的時(shí)候,我們通常有兩種比較簡(jiǎn)單的方式,一種是通過(guò)session的get()方法,另一種是load()方法,但其實(shí)這兩種是有區(qū)別的。寫(xiě)這篇文章的目的并不是為了通過(guò)Demo去給讀者演示這兩者到底是有什么區(qū)別,只是一篇總結(jié)性的文章。告訴自己需要記住Hibernate的這個(gè)點(diǎn)。
這兩種在查詢性能上是有一定區(qū)別的,但在項(xiàng)目中更傾向的肯定是load()方法。
PS,概念什么的就不詳細(xì)介紹了,主要就是列舉一下而已,因?yàn)槲易约罕旧硎菍?duì)這個(gè)點(diǎn)比較了解了。
1、get()方法來(lái)加載對(duì)象,當(dāng)我們?cè)噲D得到一個(gè)id不存在的對(duì)象時(shí)候,會(huì)報(bào)空指針異常,也就是NullPointException。
2、load()方法來(lái)加載對(duì)象,如果id不存在,若我們不使用該對(duì)象的任何屬性,啥事沒(méi)有;但如果需要使用屬性(也就是真正的去查詢?cè)搶?duì)象),會(huì)報(bào)異常,但該異常并不是空指針,而是ObjectNotFoundException。
為啥呢?還是因?yàn)檠舆t加載,得到的是僅包含ID的代理對(duì)象;雖然我們?cè)谑褂镁唧w的屬性時(shí)候,會(huì)發(fā)送SQL語(yǔ)句去進(jìn)行查詢,但卻查詢不到結(jié)果,這個(gè)就好尷尬。所以你要查詢的屬性是不存在的,所以會(huì)報(bào)ObjectNotFoundException。
3、關(guān)于load還有一點(diǎn)比較重要,就是LazyInitializationException(懶加載異常,用過(guò)Hibernate的應(yīng)該都會(huì)接觸過(guò)N次)。
其原因還是因?yàn)檠舆t加載!我們通過(guò)load方法得到了代理對(duì)象,但此時(shí)我們的session關(guān)閉了,但我們的對(duì)象還是存在的啊,所以當(dāng)我們準(zhǔn)備使用該對(duì)象屬性的時(shí)候,就會(huì)報(bào)LazyInitializationException異常了。Session都關(guān)了,我還怎么去初始化= =
提到懶加載異常,突然想到一個(gè)點(diǎn),就是我們之前在開(kāi)發(fā)web項(xiàng)目的時(shí)候,通過(guò)load()方法得到的對(duì)象,經(jīng)常會(huì)在session關(guān)閉之后再使用。那這個(gè)時(shí)候一般都是如何解決的?
答案就是OpenSessionInViewer。關(guān)于這個(gè)嘛,隨便百度有的是教程,它在Spring與Hibernate整合過(guò)程中有一個(gè)比較重要的作用。將其配置在web.xml中。
更多建議: