避免延迟的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.mzph.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…