先说相同点
这两个方法都接受实体的 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
分享到:
相关推荐
- `getReference()`:与`find()`类似,但当实体不存在时会抛出`EntityNotFoundException`异常。此外,`getReference()`返回的实体可能未初始化,仅作为引用存在。 2. **插入实体**: - `persist()`:将新创建的...
Person person = entityManager.getReference(Person.class, 1); // 在此处使用person对象之前,如果未加载实际数据,会触发懒加载 } ``` `find()`方法会立即加载对象,即使数据不在内存中,而`getReference()`...
- `<T>T getReference(Class<T> entityClass, Object pk)`:获取实体引用。 - `<T>T find(Class<T> entityClass, Object pk)`:查找实体。 - `boolean contains(Object entity)`:判断是否包含实体。 - `void ...
JPA还提供了丰富的查询API,包括简单的查询方法(find, getReference, merge, remove)和复杂的JPQL(Java Persistence Query Language)查询。JPQL允许开发者使用面向对象的方式书写查询语句,如选择、聚合、连接、...
根据提供的标题、描述、标签及部分内容,我们可以梳理出与"BBSport_java项目总结"相关的几个核心知识点:包括 DAO(Data Access Object)模式的实现、基于 JPA 的 CRUD 操作、事务管理以及服务层的设计。 ### 一、...
然而,与`find()`不同的是,当指定的主键不存在于数据库中时,`getReference()`会抛出`EntityNotFoundException`异常。这使得开发者可以在异常被捕获后进行相应的错误处理。 2. **设置提交模式(Flush Mode Type)*...
- `find()` 或 `getReference()`:获取实体对象 - `persist()`:保存新实体 - `merge()`:更新实体 - `remove()`:删除实体 - `createQuery()`:执行EJB3QL查询 - `createNativeQuery()`:执行原生SQL查询 - ...
- 使用`find()`或`getReference()`方法获取实体 - 添加实体:`persist()` - 更新实体 - 合并实体:`merge()` - 删除实体:`remove()` - 执行EJB3QL操作:`createQuery()` - 执行SQL操作:`createNativeQuery...
**3.7.2 Entity获取find()或getReference()** `find()`方法根据主键查询实体;`getReference()`仅返回实体的引用而不立即加载实体数据。 **3.7.3 持久化实体persist()** 用于将新的实体Bean保存到数据库中。 **...
**4.3 STATELESS SESSION BEAN 与 STATEFUL SESSION BEAN 的区别**: - 无状态 SessionBean 不保留客户端状态,而有状态 SessionBean 则保持。 - 有状态 Bean 适用于需要保持会话状态的场景。 **4.4 如何改变 ...
- **获取实体**:使用`find()`或`getReference()`方法检索实体对象。 - **添加实体**:使用`persist()`方法将实体对象持久化到数据库。 - **更新实体**:通过直接修改实体属性来更新数据库记录。 - **合并实体**...
- **Entity获取find()或getReference()** - 解释如何通过EntityManager获取实体Bean。 - **持久化实体persist()** - 介绍如何使用persist()方法持久化实体Bean。 - **更新实体** - 说明如何更新已存在的实体Bean...