JPA性能方法------EntityManager的find()与getReference()的区别

2024-02-24 11:58

本文主要是介绍JPA性能方法------EntityManager的find()与getReference()的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先说相同点

    这两个方法都接受实体的class和代表实体主键的对象作为参数。由于它们使用了Java泛型方法,无需任何显示的类型转换即可获得特定类型的实体对象。其中,在primaryKey上面普遍使用了java5的autoboxing(自动装箱)的特性。

    再者,就是两者都会在EntityManager关闭的情况下抛出IllegalStateException -if this EntityManager has been closed.在传入的第一个参数不是实体或者第二个参数不是一个有效的主键的情况下抛出

IlegalArgumentException -if the first argument does not denote an entity type or the secondargument is not a valid type for that entity's primary key

 

 

不同点:

    find()返回指定OID的实体,如果这个实体存在于当前的persistencecontext中,那么返回值是被缓存的对象;否则会创建一个新的实体,并从数据库中加载相关的持久状态。如果数据库不存在指定的OID的记录,那么find()方法返回null。

    getReference()方法和find()相似。不同的是:如果缓存中没有指定的实体,EntityManager会创建一个新的实体,但是不会立即访问数据库来加载持久状态,而是在第一次访问某个属性的时候才加载。此外,getReference()方法不返回null,如果数据库找不到相应的实体,这个方法会抛出javax.persistence.EntityNotFoundException。

EntityNotFoundException  -if the entity state cannot be accessed

某些场合下使用getReference()方法可以避免从数据库加载持久状态的性能开销。

 

   这里要着重提出的是两句话:

   如果缓存中没有指定的实体,EntityManager会创建一个新的实体,但是不会立即访问数据库来加载持久状态,而是在第一次访问某个属性的时候才加载。

   比如,em.find()返回的实体,我们就可以对它进行各种操作,而若对em.getReference()返回的实体,由于不会立即访问数据库来加载持久状态,对它进行的操作很可能就会出现Exception,比如在对它返回的实体做getter操作时,由于EntityManager对此采用延时加载,就会抛出org.hibernate.lazyinitializationexceptioncould not initialize proxy no session

   因此将一个新的实体传递给事务的时候通常使用find()方法,而当不连接数据库,不使用getter方法,即使用setter方法改变状态时才使用getReference()方法。(这是由于getReference返回是一个Proxy实体,即没有加载持久状态)

 

   某些场合下使用getReference()方法可以避免从数据库加载持久状态的性能开销。

    这也完全是由于getReference返回是一个Proxy实体.

    比如一个简单的update操作,先使用find()获取实体,而后使用实体的setter方法;或者是getReference()方法,而后使用实体的setter方法。

    对于前者JPA调用的SQL:select****,而后才是update ****

    对于后者:仅为update*****

 

又如:

操作                                                                            执行的SQL

em.remove(em.getReference(Person.class,1))         deletefrom Person where personid = 1

em.remove(em.find(Person.class,1))                 select* from Person where personid =1

                                                   deletefrom Person where personid =1

 

   由此可以看出,find()做了一次select的操作,而getReference并没有做有关数据库的操作,而是返回一个代理,这样它就减少了连接数据库和从数据库加载持久状态的开销。

这篇关于JPA性能方法------EntityManager的find()与getReference()的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742027

相关文章

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

macOS无效Launchpad图标轻松删除的4 种实用方法

《macOS无效Launchpad图标轻松删除的4种实用方法》mac中不在appstore上下载的应用经常在删除后它的图标还残留在launchpad中,并且长按图标也不会出现删除符号,下面解决这个问... 在 MACOS 上,Launchpad(也就是「启动台」)是一个便捷的 App 启动工具。但有时候,应

分辨率三兄弟LPI、DPI 和 PPI有什么区别? 搞清分辨率的那些事儿

《分辨率三兄弟LPI、DPI和PPI有什么区别?搞清分辨率的那些事儿》分辨率这个东西,真的是让人又爱又恨,为了搞清楚它,我可是翻阅了不少资料,最后发现“小7的背包”的解释最让我茅塞顿开,于是,我... 在谈到分辨率时,我们经常会遇到三个相似的缩写:PPI、DPI 和 LPI。虽然它们看起来差不多,但实际应用

SpringBoot日志配置SLF4J和Logback的方法实现

《SpringBoot日志配置SLF4J和Logback的方法实现》日志记录是不可或缺的一部分,本文主要介绍了SpringBoot日志配置SLF4J和Logback的方法实现,文中通过示例代码介绍的非... 目录一、前言二、案例一:初识日志三、案例二:使用Lombok输出日志四、案例三:配置Logback一

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很