在em.close()之后,延迟加载的实体会发生什么?

在em.close()之后,延迟加载的实体会发生什么?

问题描述:

我有一些实体和延迟加载的引用。在em.close()之后,延迟加载的实体会发生什么?

EntityA { 

@ManyToMany 
private List<EntityB> bs; 

} 

EntityB { 

@ManyToMany 
private List<EntityA> as; 

} 

我想知道,如果它是保存,如果他们已经加载的PC里面前访问持久化上下文(PC)外面那些慵懒的集合? E.g.

// put into PC 
a = em.merge(a); 
// trigger lazy loading 
a.bs.size(); 
em.close(); 
// access outside PC 
a.bs.size(); 

我做了一个EclipseLink的小测试,这似乎工作。但我不知道这是因为:

  1. 懒惰 - 列出使用弱引用存储和可访问的,但现在可能是GCed在某些时候,
  2. 的懒列表是从数据库中取出即使该实体不在PC中(无论出于何种原因),
  3. 即使数据库将被关闭,lazy-Lists也会随时启动并访问。

即使EM关闭,EclipseLink也会在EMF打开时保持与数据存储的连接,所以仍然可以加载惰性字段,直到关闭EMF。这可以说是违反JPA规范,许多人认为它是反模式。

其他JPA提供商将像这样做,所以,如果你想成为100%JPA符合标准,你不应该依赖于它,并确保你EM收盘前加载懒领域。如果一个字段没有被EM关闭加载,那么访问它可能会抛出异常(取决于JPA提供者)。

+0

这可能听起来很愚蠢,但是一旦初始化它就像'任何其他'的集合,对吧?背景中没有弱引用,代理或任何其他“魔术”? – kerner1000

+0

不知道。我不使用EclipseLink。为什么不尝试,并打印出收集字段的类? – DN1

+0

是的,一旦获取,实体中就像其他任何参考一样。只有在没有获取上下文的情况下才需要上下文 – Chris