EntityManager的find()与getReference()的区别
2015-07-06 14:27
351 查看
EntityManager的find()与getReference()的区别
(2010-03-09 21:18:23)转载▼
分类: EJB |
这两个方法都接受实体的 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。
EntityNotFoundException-
if the entity state cannot be accessed
某些场合下使用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并没有做有关数据库的操作,而是返回一个代理,这样它就减少了连接数据库和从数据库加载持久状态的开销。
引用出处:http://blog.csdn.net/whw1984/archive/2009/09/06/4524449.aspx
相关文章推荐
- [LeetCode] Swap Nodes in Pairs
- CSS3 Transitions, Transforms和Animation使用简介与应用展示
- JQuery.Ajax()的data参数类型
- 毫秒数到日期转换 javascript
- Nodejs和npm学习
- 第四章 javaScript运算符
- AngularJs自定义指令详解(10) - 执行次序
- AngularJs 简单实现全选,多选操作
- JSON数组多字段排序
- 【慕课网】php工程师学习计划之我的学习笔记——01 入门必学web基础 htmlcss基础课程 篇
- jquery 选择器,模糊匹配
- How do I reset a jquery-chosen select option with jQuery?重置chosen组件值状态
- Jquery+highchart+ajax
- [LeetCode][JavaScript]Power of Two
- libgdx的菜单配置,以及json文件的结构
- 7月3日 学习仿腾讯游戏首页小幻灯片jquery插件
- [LeetCode][JavaScript]Largest Number
- html之内联元素与块状元素
- css笔记11:选择器练习
- 如何将一个json中的json字符串转换成一个USER对象。