Hibernate缓存和懒加载的坑你知道多少?这5个简单问题回答不上来就不敢说会用hibernate
问题1:session.flush()调用之后,懒加载还生效吗?
如果不生效,那是抛异常还是没有任何反应,或者直接返回null?
答案:生效。可以理解为在同一个session当中,懒加载只会执行一次。
问题2: 多次调用实体类的导航属性,是否会多次进行sql查询?
如果session.flush()调用之后呢?
答案:不会进行多次sql查询,即使是在session.flush之后。
问题3:新创建的某个实体类对象,当调用session.flush()之后,能否直接加载其导航属性?
比如下方的代码,能否直接从数据库获取到ID为roleId的Role对象呢?
User user = new User(......);
user.setRoleId(roleId);
db.save(user);
db.getSession().flush();
Role role = user.getRole();
答案:不能。
问题4:多次调用session.get(Serializable id) 是否会每次都从数据库查询?

答案:否,不仅仅是从缓存里面读取,而且每次返回的竟然是同一个对象!注意,是同一个内存地址哦!
问题5:你知道ID相同的实体类(加了@Entity注解)每次返回的是同一个内存对象吗?

上图一共执行了3次sql,这个比较好理解,难以理解的是:居然上面3个employee是引用的同一个内存地址,也就是说是完完全全一模一样的同一个对象!比如我把employee1的名字改了,那么employee2的名字也就改了,真TM surprising!
既然上图里面的三个employee是同一个对象,那我们可以猜测那是因为Employee类加了@Entity注解,而这个注解会改变hashcode的值。如果查询返回一个DTO对象,是不是就应该是不同的对象了吧?马上就来验证这个猜测,看下图:

上图说明:猜对了。

上图说明:即使第2个employee是从数据库查出来的,但是由于它跟第一个employee是同一个内存对象,所以它的name属性已经被改成了内存中的那个name值了。神奇吧!
hibernate懒加载天坑:对于ManyToOne注解居然默认是FetchType.EAGER
EAGER是什么意思呢?比如User类有个role属性, 当加载user对象的时候,就会同时加载role对象,也就是你期望的只有一条简单sql从user表查询,但是却执行了两条sql(或者是join查询)。
所以,通常情况下对于ManyToOne注解,都需要手工设置fetch = FetchType.LAZY,否则会出现严重性能问题。
本文中的测试来自jframe 框架
基于spring mvc搭建的多层级多模块java web应用程序框架。包含:基础设施层、数据库定义规范、数据库访问规范、日志记录规范、多层级异常捕获、标准ajax规范、母版页规范、视图呈现规范、JavaScript框架规范等。实际上该框架定义的规范极其详细,比如数据库定义层:枚举类使用规范、datetime/bool/string字段规范、1对1、1对多、多对1、多对多外键关系映射规范、父类定义规范、字段注释规范、懒加载规范等等。。。
技术交流QQ群:651499479,欢迎java大神指点迷津,也欢迎新手进群学习。
github地址: https://github.com/leotsai/jframe
THE END.
Hibernate缓存和懒加载的坑你知道多少?这5个简单问题回答不上来就不敢说会用hibernate的更多相关文章
- 解决hibernate中的懒加载(延迟加载)问题
解决hibernate中的懒加载(延迟加载)问题 我们在开发的时候经常会遇到延迟加载问题,在实体映射时,多对一和多对多中,多的一样的属性默认是lazy="true"(即,默认是 ...
- Hibernate中的一级缓存、二级缓存和懒加载(转)
1.为什么使用缓存 hibernate使用缓存减少对数据库的访问次数,从而提升hibernate的执行效率.hibernate中有两种类型的缓存:一级缓存和二级缓存. 2.一级缓存 Hibenate中 ...
- Hibernate中的一级缓存、二级缓存和懒加载
1.为什么使用缓存 hibernate使用缓存减少对数据库的访问次数,从而提升hibernate的执行效率.hibernate中有两种类型的缓存:一级缓存和二级缓存. 2.一级缓存 Hibenate中 ...
- Hibernate一级缓存之懒加载问题
Hibernate的懒加载: 当用到数据的时候才向数据库查询,这就是hibernate的懒加载特性. 目的,为提高程序执行效率. 查询操作:get()方法/load()方法 (1)get()方法,及时 ...
- Rest风格中关于JPA使用懒加载的坑
公司最近使用的ORM框架是JPA实现产品使用的是hibernate,曾经看过一篇博客上面说的是如果团队里面没有一个精通hibernate的人,那么最好不要使用它,我现在是深刻的体会到了.但是使用什么框 ...
- mybatis和hibernate中的懒加载
概念:所谓懒加载就是延时加载,延迟加载.什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载.至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减 ...
- hibernate JPA 使用懒加载时代理对象
hibernate延迟加载代理对象实际对象读取方式 public static <T> T deproxy (T obj) { if (obj == null) return obj; i ...
- hibernate 多对多 懒加载问题
报错:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: net. ...
- hibernate中的懒加载和急加载
懒加载(FatchType.LAZY)是Hibernate为提高程序执行效率而提供的一种机制,简单说就是只有正真使用其属性的时候,数据库才会进行查询. 具体的执行过程就是:Hibernate从数据库获 ...
随机推荐
- Unicode字符集和编码方式
通常将一个标准中能够表示的所有字符的集合称为字符集,比如ISO/Unicode所定义的字符集为Unicode.在Unicode中,每个字符占据一个码位/Unicode 编号(用4位十六进制数表示,Co ...
- Kotlin入门第二课:集合操作
测试项目Github地址: KotlinForJava 前文传送: Kotlin入门第一课:从对比Java开始 初次尝试用Kotlin实现Android项目 1. 介绍 作为Kotlin入门的第二课, ...
- (入门篇 NettyNIO开发指南)第五章-分隔符和定长解码器使用
TCP 以流的方式进行数据传输上层的应用协议为了对消息进行区分,往往采用如下4种方式. (1)消息长度固定,累计读取到长度总和为定长LEN 的报文后,就认为读取到了一个完整的消息,将计数器置位, ...
- struts2.1.6教程四_2、ActionContext 、ValueStack 、Stack Context
ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext.getContext() Va ...
- js中 substr(), substring(), slice()的区别
一.作用 三者都是基于原字符串创建新字符串的方法. 接收一到两个参数,第一个参数截取字符串的开始位置(字符下标,从0开始),第二个参数因方法不同而不同,后面不同点会说到. 另外,三个方法都不会修改原字 ...
- Libevent源码分析—event_set()
初始化完event_base后,下面要初始化event,通过调用event_set()实现 .相关源码位于event.c event_set() void event_set(struct event ...
- 每天一个JS 小demo之商品下架特效制作,主要知识点:定时器,倒计时,抖动特效。PS:由于不方便上传文件夹,只能上传效果图,图片等素材需自寻哟。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- JavaScript面向对象轻松入门之概述(demo by ES5、ES6、TypeScript)
写在前面的话 这是一个JavaScript面向对象系列的文章,本篇文章主要讲概述,介绍面向对象,后面计划还会有5篇文章,讲抽象.封装.继承.多态,最后再来一个综合. 说实话,写JavaScript面向 ...
- MPP 二、Greenplum数据加载
Loading external data into greenplum database table using different ways... Greenplum 有常规的COPY加载方法,有 ...
- 分享几个python小脚本
by 梁凯 今天我想给大家分享几个python脚本,分别是: 1.公司访问外网认证脚本(最初有同事写过,我优化了一下). 2.统计周报系统所有同事的最近一篇周报. 3.统计测试技术分享里指定一个月所有 ...