溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Hibernate中實(shí)例化集合和代理

發(fā)布時(shí)間:2021-12-04 16:33:19 來源:億速云 閱讀:134 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“怎么在Hibernate中實(shí)例化集合和代理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“怎么在Hibernate中實(shí)例化集合和代理”吧!

Hibernate中實(shí)例化集合和代理在Session范圍之外訪問未初始化的集合或代理,Hibernate將會(huì)拋出LazyInitializationException異常。 也就是說,在分離狀態(tài)下,訪問一個(gè)實(shí)體所擁有的集合,或者訪問其指向代理的屬性時(shí),會(huì)引發(fā)此異常。

有時(shí)候我們需要保證某個(gè)代理或者集合在Session關(guān)閉前就已經(jīng)被初始化了。 當(dāng)然,我們可以通過強(qiáng)行調(diào)用cat.getSex()或者cat.getKittens().size()之類的方法來確保這一點(diǎn)。 但是這樣的程序會(huì)造成讀者的疑惑,也不符合通常的代碼規(guī)范。

靜態(tài)方法Hibernate.initialized() 為你的應(yīng)用程序提供了一個(gè)便捷的途徑來延遲加載集合或代理。 只要它的Session處于open狀態(tài),Hibernate.initialize(cat) 將會(huì)為cat強(qiáng)制對(duì)代理實(shí)例化。 同樣,Hibernate.initialize( cat.getKittens() ) 對(duì)kittens的集合具有同樣的功能。

還有另外一種選擇,就是保持Session一直處于open狀態(tài),直到所有需要的集合或代理都被載入。 在某些應(yīng)用架構(gòu)中,特別是對(duì)于那些使用Hibernate進(jìn)行數(shù)據(jù)訪問的代碼,以及那些在不同應(yīng)用層和不同物理進(jìn)程中使用Hibernate的代碼。 在集合實(shí)例化時(shí),如何保證Session處于open狀態(tài)經(jīng)常會(huì)是一個(gè)問題。有兩種方法可以解決此問題:

在一個(gè)基于Web的應(yīng)用中,可以利用servlet過濾器(filter),在用戶請(qǐng)求(request)結(jié)束、頁面生成 結(jié)束時(shí)關(guān)閉Session(這里使用了在展示層保持打開Session模式(Open Session in View)), 當(dāng)然,這將依賴于應(yīng)用框架中異常需要被正確的處理。

在返回界面給用戶之前,乃至在生成界面過程中發(fā)生異常的情況下, 正確關(guān)閉Session和結(jié)束事務(wù)將是非常重要的, 請(qǐng)參見Hibernate wiki上的"Open Session in View"模式,你可以找到示例。

在一個(gè)擁有單獨(dú)業(yè)務(wù)層的應(yīng)用中,業(yè)務(wù)層必須在返回之前,為web層“準(zhǔn)備”好其所需的數(shù)據(jù)集合。這就意味著 業(yè)務(wù)層應(yīng)該載入所有表現(xiàn)層/web層所需的數(shù)據(jù),并將這些已實(shí)例化完畢的數(shù)據(jù)返回。

通常,應(yīng)用程序應(yīng)該 為web層所需的每個(gè)集合調(diào)用Hibernate.initialize()(這個(gè)調(diào)用必須發(fā)生咱session關(guān)閉之前); 或者使用帶有FETCH從句,或FetchMode.JOIN的Hibernate查詢, 事先取得所有的數(shù)據(jù)集合。

如果你在應(yīng)用中使用了Command模式,代替Session Facade , 那么這項(xiàng)任務(wù)將會(huì)變得簡(jiǎn)單的多。

你也可以通過merge()或lock()方法,在訪問未實(shí)例化的集合(或代理)之前, 為先前載入的對(duì)象綁定一個(gè)新的Session。

顯然,Hibernate將不會(huì),也不應(yīng)該自動(dòng)完成這些任務(wù),因?yàn)檫@將引入一個(gè)特殊的事務(wù)語義。

有時(shí)候,你并不需要完全實(shí)例化整個(gè)大的集合,僅需要了解它的部分信息(例如其大?。?、或者集合的部分內(nèi)容。

你可以使用集合過濾器得到其集合的大小,而不必實(shí)例化整個(gè)集合:

( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()

這里的createFilter()方法也可以被用來有效的抓取集合的部分內(nèi)容,而無需實(shí)例化整個(gè)集合:

s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();

到此,相信大家對(duì)“怎么在Hibernate中實(shí)例化集合和代理”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI