Hibernate操作延遲加載的關(guān)聯(lián)
Hibernate操作延遲加載的關(guān)聯(lián)有很多值得學(xué)習(xí)的地方,這里我們主要介紹Hibernate延遲,包括介紹Hibernate延遲使用等方面。
默認情況下,Hibernate 3對集合使用延遲select抓取,對返回單值的關(guān)聯(lián)使用延遲代理抓取。對幾乎是所有的應(yīng)用而言,其絕大多數(shù)的關(guān)聯(lián),這種策略都是有效的。
注意:假若你設(shè)置了hibernate.default_batch_fetch_size,Hibernate會對延遲加載采取批量抓取優(yōu)化措施(這種優(yōu)化也可能會在更細化的級別打開)。
然而,你必須了解延遲抓取帶來的一個問題。在一個打開的Hibernate session上下文之外調(diào)用延遲集合會導(dǎo)致一次意外。比如:
- s = sessions.openSession();
- Transaction tx = s.beginTransaction();
- User u = (User) s.createQuery("from User u where u.name=:userName")
- .setString("userName", userName).uniqueResult();
- Map permissions = u.getPermissions();
- tx.commit();
- s.close();
- Integer accessLevel = (Integer) permissions.get("accounts"); // Error!
在Session關(guān)閉后,permessions集合將是未實例化的、不再可用,因此無法正常載入其狀態(tài)。 Hibernate對脫管對象不支持延遲實例化. 這里的修改方法是:將permissions讀取數(shù)據(jù)的代碼 移到tx.commit()之前。
除此之外,通過對關(guān)聯(lián)映射指定lazy="false",我們也可以使用非延遲的集合或關(guān)聯(lián)。
但是, 對絕大部分集合來說,更推薦使用延遲方式抓取數(shù)據(jù)。如果在你的對象模型中定義了太多的非延遲關(guān)聯(lián),Hibernate最終幾乎需要在每個事務(wù)中載入整個數(shù)據(jù)庫到內(nèi)存中!
但是,另一方面,在一些特殊的事務(wù)中,我們也經(jīng)常需要使用到連接抓取(它本身上就是非延遲的),以代替查詢抓取。
這里我們就不再說明如何具體的定制Hibernate中的抓取策略。在Hibernate3中,具體選擇哪種抓取策略的機制是和選擇單值關(guān)聯(lián)或集合關(guān)聯(lián)相一致的。
【編輯推薦】