EntityManager.find()和EntityManger.getReference()有什么区别?

什么是区别

<T> T EntityManager.find(Class<T> entityClass, Object primaryKey) and <T> T EntityManager.getReference(Class<T> entityClass, Object primaryKey) 

我认为getReference返回实体,如果它被pipe理。 并find返回实体,如果它被pipe理,否则在数据库上执行SQL以使其进行pipe理。

请确认。


上下文:从webapp获取要删除的对象的主键(pk的types为long); 要把实体pipe理删除。

 EntityManager.remove(Object entity) 

通过pipe理实体到entitymanager删除方法“最好的和正确的select? find或得到引用?

正如你所知,JPA有一个EntityManager的概念。 在实体pipe理器中工作期间,某些对象从数据库中加载,可以被修改,然后刷新到数据库。

find()必须返回对象的初始化实例。 如果它尚未加载到EntityManager中,则从数据库中检索它。

getReference()被允许返回一个代理,而不是一个初始化的实例,如果实体没有被加载到EntityManager之前。 在这个代理中,只有主键属性被初始化。 代理可以在不碰到数据库的情况下创build,因为唯一的初始化属性已经被赋予了getReference()函数。

当你有一个实体A引用一个实体B,并且你希望把B的b属性设置为B,而不必从数据库中加载B时,后者是有用的。

只有当您引用B的其他属性时,代理才会被初始化。

getReference()不会检索完整的对象,而只是一个代理,因此,如果不访问对象的成员,效率会更高。

例如,当创build一个新的对象插入数据库时​​,可能需要引用另一个已经存储在数据库中的对象。

要使JPA正确存储新对象,只需要引用对象的主键。 通过使用getReference()您可以获得包含主键的代理,并节省加载完整对象的成本。

本书从GlassFish 3开始Java EE 6平台,在第135页中提到了不同之处:“通过ID查找”

find()如果find()了实体,则返回; 如果找不到,则返回空值。

 MyEntity obj = em.find(MyEntity.class, id); if(obj != null){ // Process the object } 

getReference()适用于需要托pipe实体实例的情况,但不能访问实体的主键以外的任何数据。

 try { MyEntity obj = em.getReference(MyEntity.class, id); // Process the object } catch (EntityNotFoundException e) { // Entity Not Found }