【问题标题】:What is the difference between EntityManager.find() and EntityManger.getReference()?EntityManager.find() 和 EntityManger.getReference() 有什么区别?
【发布时间】:2011-07-25 19:48:47
【问题描述】:

有什么区别

<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 方法'什么是更好和正确的选择?查找或获取引用?'

【问题讨论】:

标签: java jpa entitymanager


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 很好的解释。谢谢丹尼尔。如果实体已经加载,没有区别吗?
  • 实际上 getReference 返回的对象不一定是任何“代理”,因为这是一个实现细节;有些将返回“代理”,而其他(支持字节码增强)将返回真实类型但延迟加载的对象。虽然您避免了调用此方法时的数据库命中,但稍后在加载字段时可能会获得多个数据库访问
  • 一个需要提前注意的警告:将 getReference() 与继承结合可能会导致 'instanceof' 以预期的方式运行。有一些方法可以解决这个问题,主要是使用访问者模式,在这里讨论:stackoverflow.com/questions/3540489/…
  • @Daniel 如果 getReference 调用的实体中有版本注释会发生什么?
  • 没什么特别的AFAIK,我们也使用@Version。并且版本不相关,因为它不是密钥的一部分。它仅在保存相关实体时使用。
【解决方案2】:

Beginning Java EE 6 Platform with GlassFish 3这本书,在第135页提到不同之处:“Finding By 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
}

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-02
      • 2011-12-12
      • 2010-09-16
      • 2012-03-14
      • 2012-02-06
      • 2011-02-25
      • 2011-11-22
      • 2015-03-26
      相关资源
      最近更新 更多