48

有什么区别

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

?

我认为 getReference 如果它是托管的,它会返回实体。如果它是托管的,则 find 返回实体,否则在数据库上执行 SQL 以使其托管。

请确认。


上下文:从 webapp 我得到要删除的对象的主键(长类型的 pk);到实体应该被管理删除。

EntityManager.remove(Object entity)

将托管实体传递给 entitymanager remove 方法'什么是更好和正确的选择?查找或获取参考?

4

3 回答 3

79

如您所知,JPA 具有 EntityManager 的概念。在实体管理器中工作期间,一些对象从数据库中加载,可以修改并随后刷新到数据库中。

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

getReference()如果实体之前未在 EntityManager 中加载,则允许返回代理而不是初始化实例。在这个代理中,只有主键属性被初始化。可以在不访问数据库的情况下创建代理,因为唯一的初始化属性已经提供给 getReference() 函数。

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

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

于 2011-03-30T06:02:18.767 回答
9

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

例如,在创建要插入数据库的新对象时,它可能必须引用已存储在数据库中的另一个对象。

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

于 2011-03-30T05:40:05.290 回答
9

《使用 GlassFish 3 开始 Java EE 6 平台》一书,在第 135 页提到了差异:“按 ID 查找”

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

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

getReference()适用于需要托管实体实例但没有数据(可能是实体的主键)被访问的情况。

try {
    MyEntity obj = em.getReference(MyEntity.class, id);
    // Process the object
} catch (EntityNotFoundException e) {
    // Entity Not Found
}
于 2013-02-27T23:02:43.573 回答