在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的小测试,这似乎工作。但我不知道这是因为:
- 懒惰 - 列出使用弱引用存储和可访问的,但现在可能是GCed在某些时候,
- 的懒列表是从数据库中取出即使该实体不在PC中(无论出于何种原因),
- 即使数据库将被关闭,lazy-Lists也会随时启动并访问。
答
即使EM关闭,EclipseLink也会在EMF打开时保持与数据存储的连接,所以仍然可以加载惰性字段,直到关闭EMF。这可以说是违反JPA规范,许多人认为它是反模式。
其他JPA提供商将不像这样做,所以,如果你想成为100%JPA符合标准,你不应该依赖于它,并确保你EM收盘前加载懒领域。如果一个字段没有被EM关闭加载,那么访问它可能会抛出异常(取决于JPA提供者)。
这可能听起来很愚蠢,但是一旦初始化它就像'任何其他'的集合,对吧?背景中没有弱引用,代理或任何其他“魔术”? – kerner1000
不知道。我不使用EclipseLink。为什么不尝试,并打印出收集字段的类? – DN1
是的,一旦获取,实体中就像其他任何参考一样。只有在没有获取上下文的情况下才需要上下文 – Chris