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 second argument is not a valid type for that entity‘s primary key

不同点:

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

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

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

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

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

比如,em.find()返回的实体,我们就可以对它进行各种操作,而若对em.getReference()返回的实体,由于不会立即访问数据库来加载持久状态,对它进行的操作很可能就会出现Exception,比如在对它返回的实体做getter操作时,由于EntityManager对此采用延时加载,就会抛出org.hibernate.lazyinitializationexception could 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))         delete from Person where personid = 1

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

delete from Person where personid =1

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

another link:

http://blog.csdn.net/hongtaq/article/details/8026798

时间: 2024-08-25 14:46:10

EntityManager的find()与getReference()的区别的相关文章

JPA的entityManager的find、getReference、persisit、remove方法的使用

场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 在上面博客中搭建好JPA的HelloWorld后,再新建test包,包下新建Junit测试类 然后将JPA所需的API对象等声明 private EntityManagerFactory entityManagerFactory; private EntityManager entityManage

JPA 缓存

JPA  缓存 对于JPA2.0,缓存分为一级缓存和二级缓存(JPA1.0只支持一级缓存).二级缓存通常是用来提高应用程序性能的,它可以避免访问以已经从数据库加载的数据,提高访问未被修改数据对象的速度. 持久化上下文就是JPA的一级缓存,通过在持久化上下文中存储持久化状态实体的快照,既可以进行脏检测,还可以当做持久化实体的缓存.一级缓存属于请求范围级别的缓存,如下 JPA二级缓存是跨越持久化上下文的,是真正意义上的全局应用缓存,如下 如果二级缓存激活,JPA会先从一级缓存中寻找实体,未找到再从二

JPA学习笔记(5)——EntityManager相关

Persistence EntityManagerFactory EntityManager find方法 getReference方法 persist方法 remove方法 merge方法 情况1传入的对象没有id 情况2传入的对象有identityManager的缓存中没有该对象数据库中没有该记录 情况3传入的对象有identityManager的缓存没有该对象数据库中有该记录 情况4传入的对象有identityManager的缓存有该对象 flush方法 refresh方法 clear c

转载 j2ee j2se j2me 区别,mvc 和ssh联系理解

[转]J2SE J2EE J2ME的区别 以及 MVC与SSH对应关系 2014-3-6阅读322 评论0 J2SE J2EE J2ME的区别多数编程语言都有预选编译好的类库以支持各种特定的功能,在Java中,类库以包(package)的形式提供,不同版本的Java提供不同的包,以面向特定的应用. Java2平台包括标准版(J2SE).企业版(J2EE)和微缩版(J2ME)三个版本:Standard Edition(标准版) J2SE 包含那些构成Java语言核心的类.比如:数据库连接.接口定义

spring-data-jpa中findOne与getOne的区别

项目中用到了spring-data-jpa,今天在写一个update方法的时候报了个空指针,看了看是因为一个对象中的关联没有取出来,我用的是getOne取得这个对象,加断点看以一下这个对象是个hibernate的代理对象,而不是实体,里面基本没有值. 然后我又换成findOne试了一下,断点查看这个取出来的对象,这个对象是实体,关联也有. findOne与getOne的注释中也有些帮助 /**      * Retrieves an entity by its id.      *       

1.EntityManaget的persist和merge方法的区别

1.persist和merge的区别: Persist:添加 Merge : 分两种情况,当对象存在id,则修改:当对象不存在id则添加. 看个例子: 1 1 public class Account { 2 2 private AccountRole accountRole; 3 3 @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) 4 4 public AccountRole getAccountRole()

jpa2.0以上findOne和getOne的区别

/** * Returns a single entity matching the given {@link Example} or {@literal null} if none was found. * * @param example must not be {@literal null}. * @return a single entity matching the given {@link Example} or {@link Optional#empty()} if none wa

EntityManager方法简介

EntityManager 是用来对实体Bean 进行操作的辅助类.他可以用来产生/删除持久化的实体Bean,通过主键查找实体bean,也可以通过EJB3 QL 语言查找满足条件的实体Bean.实体Bean 被EntityManager 管理时,EntityManager跟踪他的状态改变,在任何决定更新实体Bean 的时候便会把发生改变的值同步到数据库中.当实体Bean 从EntityManager 分离后,他是不受管理的,EntityManager 无法跟踪他的任何状态改变.EntityMan

06 EntityManager和EntityTransaction

EntityManager 在 JPA 规范中, EntityManager是完成持久化操作的核心对象.实体类作为普通 java对象,只有在调用 EntityManager将其持久化后才会变成持久化对象.EntityManager对象在一组实体类与底层数据源之间进行 O/R 映射的管理.它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体. 我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作 方法