避免延遲的JPA集合

Hibernate(實際上是JPA)具有集合映射:@ OneToMany,@ ManyToMany,@ ElementCollection。 所有這些默認情況下都是惰性的。 這意味著集合是List或Set接口的特定實現,其中包含對持久會話的引用,并且只有在訪問集合時才從數據庫中加載值。 如果您僅偶爾使用集合,則可以節省不必要的數據庫查詢。

但是,這有一個問題。 在我看來,異常是第二個最常見的異常(在NullPointerException之后),即LazyInitializationException。 問題在于會話通常為您的服務層打開,并且在您將實體返回到視圖層后立即關閉。 當您嘗試在視圖中迭代未初始化的集合時(例如jsp),該集合將引發LazyInitializationException,因為它們所擁有的引用所在的會話已經關閉,并且無法獲取這些項。

如何解決? 所謂的OpenSessionInView / OpenEntityManagerInView“模式”。 簡而言之:您可以創建一個過濾器,以在請求啟動時打開會話,并在呈現視圖后(而不是在服務層完成后)關閉會話。 有人稱其為反模式,因為它將持久性處理泄漏到視圖層,并使設置復雜化。 我不會說那么糟糕:通常,它可以解決問題而不引入其他問題。 但是在我參與的所有最新項目中,我們沒有使用OpenSessionInView,而且效果很好。

之所以能正常工作,是因為我們沒有使用惰性集合。 但是,您會正確地指出,當您加載單個實體時,您將獲取“整個世界”。 好吧,不。 * ToMany映射有兩種類型:

  • 值類型映射,集合在邏輯上不包含十幾個元素。 在大多數情況下,這是@ElementCollection,還有@ * ToMany,它們帶有諸如“ Category”或“ Price”之類的項,它們只是更復雜的值對象,但自身不包含任何其他映射。 這些類型的集合的另一個共同特征是它們通常與它們自己的實體一起顯示在UI中。 例如,您最有可能要顯示文章的類別。 對于這種類型的集合,EAGER是更好的選擇。 無論如何,您都必須獲取它們,為什么不讓休眠(或任何jpa實現)想到一些巧妙的連接呢? 就像我說的那樣-邏輯上集合不超過一打或十二個,因此獲取它們不會對性能造成影響。 而且,從邏輯上講,它們不會與它們一起獲取大對象圖。
  • 大型核心實體之間的映射。 可以是“用戶所下的所有訂單”或“組織中的所有用戶”,“供應商的所有項目”等。您當然不想急于獲取它們。 因為如果您為一個組織獲取2000個用戶,那么每個組織又有1000個訂單,而一個訂單平均有3個項目,這反過來又包含所有購買該項目的人的集合。.您將最終擁有整個數據庫在記憶中。 顯然您需要惰性集合,對嗎? 好吧,不。 在這種情況下,您根本不應該使用集合映射。 在99%的情況下,這些類型的關系顯示在UI的頁面列表中。 或在搜索結果中。 它們永遠不會(也永遠不會)全部顯示在一個屏幕上(或者,如果您的應用程序提供了類似REST API之類的東西,則很少應該在一個API調用中返回它們)。 您必須對其進行查詢,并使用query.setMaxResults和query.setFirstResult()(或使用一些限制性條件來限制它們)。 此外,對集合進行映射意味著有人會在某個時候嘗試使用它們,這可能會失敗。 并且如果對象已序列化(xml,json等),則將獲取集合內容。 您幾乎肯定不想發生的事情。 (這里的想法草案:JPA可以有一個PagedList集合,該集合將允許分頁的延遲提取,從而消除了查詢的需要)

所以我剛才說的是-永遠不要使用惰性集合。 將eager集合用于非常簡單的淺表映射,將分頁查詢用于較大的映射。

好吧,不完全是。 延遲集合在那里并且它們有應用,盡管它是相當有限的。 或者,至少它們比所使用的方法不太適用。 這是我發現適用的示例場景。 在我的附帶項目中,我有一個Message實體,并且它包含一個Picture實體的集合。 用戶上載圖片時,它將存儲在該集合中。 一條消息最多可以包含10張圖片,因此非常希望收藏。 但是,然后,Message是最常用的實體–實際上是在每個請求中獲取的。 但是只有一些消息帶有圖片(您的信息流中有多少條推文有圖片上傳?)。 因此,我不想讓休眠狀態進行查詢只是為了查找給定消息沒有圖片。 因此,我將圖片數量存儲在一個單獨的字段中,使圖片集合變得懶惰,并且僅在圖片數量> 0時才手動對其進行Hibernate.initialize(..)。

因此,在某些情況下,當實體具有屬于上述第一類的可選集合時(“小型淺表集合”)。 因此,如果它很小,很淺并且是可選的(例如,在不到20%的情況下使用),則應該使用Lazy來保存不必要的查詢。

其他方面–懶惰的收藏會讓您的生活更艱難。

參考:在Bozho的技術博客上, 避免與我們的JCG合作伙伴 Bozho一起使用懶惰的JPA Collections 。

相關文章 :

  • 休眠陷阱
  • DataNucleus 3.0與Hibernate 3.5
  • Hibernate映射集合性能問題
  • ORM問題
  • 框架使開發人員愚蠢嗎?
  • 每個程序員都應該知道的事情
  • Java最佳實踐

翻譯自: https://www.javacodegeeks.com/2011/10/avoid-lazy-jpa-collections.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374860.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374860.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374860.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2016年,我的和自己談談

2016年過去三分之一了,現在談規劃晚點但總比沒想法強。想了半天還是從這個方面著手吧: 一.升級改造自己的辦公學習環境: 給自己的電腦加內存,加SSD,再添置一個顯示器,換上心儀已久的cherry青軸鍵盤&#xf…

C語言的四舍五入實現

習題3-2 高速公路超速處罰 (15 分) 按照規定,在高速公路上行使的機動車,達到或超出本車道限速的10%則處200元罰款;若達到或超出50%,就要吊銷駕駛證。請編寫程序根據車速和限速自動判別對該機動車的處理。 輸入格式: 輸入在一行中…

ACTGame項目

項目地址:https://github.com/alonecat06/ACTGame游戲地址:http://pan.baidu.com/s/1hqD3IYw 項目是一個自制單機動作游戲demo,方向是手游,使用Unity5,5月中開工至今。 做這個項目,是為加深自己對Unity的理…

Xuggler教程:幀捕獲和視頻創建

注意:這是我們的“ Xuggler開發教程 ”系列的一部分。 到目前為止,在我們的Xuggler教程系列中,我們已經對視頻處理的Xuggler進行了介紹,并討論了轉碼和媒體修改 。 在本教程中,我們將看到如何解碼視頻和捕獲幀&#xf…

面向對象-原型對象

創建對象 Js中可以用構造函數模式創建對象,如: function Person(name, age, job) {this.name name;this.age age;this.job job;this.sayName function () {alert(this.name);}}var person1 new Person("Nicholas", 29, "aa");v…

索引類型

1.B樹索引 在Oracle中是通用索引,是創建索引時的默認索引。B樹索引可以是單列索引,也可以是組合/復合索引。B樹索引最多可以包括22列。 2.位圖索引 位圖索引時決策支持系統(DSS)和數據倉庫的理想選擇,它們不應該用于事…

C語言條件運算符

先看一個error error: lvalue required as left operand of assignment| i 0 ? X 1.0 : X * x;修改后 i 0 ? (X 1.0) : (X * x);也就是說條件運算符可以執行語句,當是賦值語句時要加括號規定優先級,不然會干擾程序判斷。 因為條件運算符作為三目…

EJB 3.0注入和查找簡介

介紹 Enterprise JavaBeans Specification v。3.0引入了簡化的,基于注釋的API,用于EJB注入和查找。 EJB 3.0現在是POJO,可以使用簡單的注釋將其注入其他組件(例如EJB和Servlet)。 EJB 3.0是Java EE 6的許多其他基于POJ…

SignalR + MVC5 簡單示例

SignalR MVC5 簡單示例 原文:SignalR MVC5 簡單示例本文和前一篇文章很類似,只不過是把 SignalR 應用在了 MVC 中 新建項目,選擇 MVC 模板 安裝 SignalR Install-Package Microsoft.AspNet.SignalR 在項目中添加文件夾 Hubs 在 Hubs 文件夾中添加 Sign…

Java內存模型–快速概述和注意事項

在計算中, 內存模型描述了線程如何通過內存進行交互,或更一般地,它指定了為分段內存或分頁內存平臺生成代碼時允許編譯器進行的假設。 在給定程序和該程序的執行跟蹤的情況下,它實質上描述了執行跟蹤是否是該程序的合法執行。 Jav…

6-7 統計某類完全平方數 (20 分)

本題要求實現一個函數,判斷任一給定整數N是否滿足條件:它是完全平方數,又至少有兩位數字相同,如144、676等。 函數接口定義: int IsTheNumber ( const int N );其中N是用戶傳入的參數。如果N滿足條件,則該…

C#中數組、ArrayList和List三者的區別(轉) ,加修改

在C#中數組&#xff0c;ArrayList&#xff0c;List都能夠存儲一組對象&#xff0c;那么這三者到底有什么樣的區別呢。 數組 數組在C#中最早出現的。在內存中是連續存儲的&#xff0c;所以它的索引速度非常快&#xff0c;而且賦值與修改元素也很簡單。 <span style"font…

phpmyadmin mysql Access denied for user 'root'@'localhost'問題解決

centos6.4 32位的vps上裝了lnmp以后&#xff0c;phpmyadmin無法連接mysql服務器&#xff0c;ssh命令行里mysql -uroot -p 命令后老是出現拒絕連接的情況。php程序里也是拒絕連接。嘗試過修改phpmyadmin的config.inc.php文件&#xff0c;嘗試過修改my.cnf文件&#xff0c;嘗試過…

帶有Spring和Maven教程的JAX–WS

Spring框架通過JAX-WS提供對Web服務的遠程支持&#xff0c;實際上&#xff0c;如Spring 參考文檔中所述 &#xff0c;有三種將Spring POJO服務公開為JAX-WS Web服務的方式&#xff1a; 公開基于Servlet的Web服務&#xff08;適用于Java EE 5環境&#xff09; 導出獨立的Web服…

7-2 然后是幾點 (15 分)

7-2 然后是幾點 (15 分) 有時候人們用四位數字表示一個時間&#xff0c;比如 1106 表示 11 點零 6 分。現在&#xff0c;你的程序要根據起始時間和流逝的時間計算出終止時間。 讀入兩個數字&#xff0c;第一個數字以這樣的四位數字表示當前時間&#xff0c;第二個數字表示分鐘…

CXF學習(2) helloworld

0.新建一個項目取名wsserver. pom.xml 文件如下 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd…

Hive 接口介紹(Web UI/JDBC)

Hive 接口介紹&#xff08;Web UI/JDBC&#xff09; 實驗簡介 本次實驗學習 Hive 的兩種接口&#xff1a;Web UI 以及 JDBC。 一、實驗環境說明 1. 環境登錄 無需密碼自動登錄&#xff0c;系統用戶名shiyanlou&#xff0c;密碼shiyanlou 2. 環境介紹 本實驗環境采用帶桌面的Ubu…

Java最佳實踐– Char到Byte和Byte到Char的轉換

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將討論String性能調優。 特別是&#xff0c;我們將重點介紹使用默認編碼時如何有效地處理字符到字節和字節到字符的轉換。 本文總結了兩種提議的自定義方法與兩種經典方法&#xff0…

IOS-C文件的創建于初始化函數.void init() write_file()

//文件初始化 void init(){ FILE * fpNULL; fpfopen("telbook.data", "rb"); int count0; if (fpNULL) //沒有這個文件就把這個文件創建出來 { fpfopen("tellbook.data", "wb"); fwrite(&count, sizeof(count), 1, fp); fclose(…

7-3 逆序的三位數 (10 分)

7-3 逆序的三位數 (10 分) 程序每次讀入一個正3位數&#xff0c;然后輸出按位逆序的數字。注意&#xff1a;當輸入的數字含有結尾的0時&#xff0c;輸出不應帶有前導的0。比如輸入700&#xff0c;輸出應該是7。 輸入格式&#xff1a; 每個測試是一個3位的正整數。 輸出格式&a…