2015-09-21 48 views
1

我在Eclipse SE中使用EclipseLink作为Java SE项目中的JPA提供程序。我已经正确配置了编织以允许延迟加载。与Hibernate(抛出LazyInitializationException)不同,EclipseLink可以获得LAZY关系的代理,即使是关闭了EntityManager也是如此。要运行此查询,它会从池中获取新连接。JPA + EclipseLink - 使用已关闭的EntityManager进行延迟加载

是否有一些设置禁用或更改此功能的行为?当我尝试访问一个未加载的属性时(例如Hibernate),我需要得到一个空值或一个异常。

实施例:

List<Customer> customers = entityManager.createQuery("from Customer c", Customer.class).getResultList(); 
entityManager.close(); // Closing the EntityManager 

for (Customer customer: customers) { 
    customer.getAddress(); // Here EclipseLink executes a query to get the relationship. 
} 

感谢。

回答

0

模式“jpa session in view”是你的朋友。基本上:在请求循环期间你可以打开EntityManager(很早或根据请求),不要关闭你的应用程序代码(可以获取所有懒惰元素)并在最后一次操作之一中自动关闭EM。

我有同样的问题。 我个人使用检票,取代

class MyWebRequestCycle extends RequestCycle { 
... // extract from bigger project 
protected void onEndRequest() { 
     super.onEndRequest(); 
     if (em != null) { 
      if (em instanceof MyEntityManager) { 
       MyEntityManager em2 = (MyEntityManager) em; 
       em2.original.close(); 
      } else 
       em.close(); 
      em = null; 
     } 
} 

}

MyEntityManager是代理(在Eclpse几乎产生的)在早期EntityManager打开。上面的'如果'是因为申请的开始,这不是我们讨论的一部分。

在其他框架中以适当的方式。这取决于你。

答案有两个路径:完整的JEE容器(程序员代码无需打开或关闭EM)和servlet容器。我的答案是第二个。

备注:单词会话在这种模式下不是web会话或者没有会话感知入口参数的JPA引擎。这只是字;)

+0

谢谢,但这种模式并没有解决我的问题。我需要EclipseLink不会使查询返回LAZY关系,我需要它返回null。 –

+0

我建议反对“公开会议”: http://blog.jhades.org/open-session-in-view-pattern-pros-and-cons/ https:// blog。frankel.ch/the-opensessioninview-antipattern 它被认为是Hibernate中的反模式,我怀疑EclipseLink认为它好得多。 –

2

即使关闭了EntityManager,EclipseLink也允许您访问懒关系。此行为是EclipseLink特有的,不属于JPA规范的一部分。

当连接关闭时,您将得到您要查找的异常。

但是,EclipseLink正在将未实例化的列表包装到IndirectList中。您可以通过编程检查列表是否已实例化。

if(customers instanceof IndirectList) { 
    boolean foo = ((IndirectList) customers).isInstantiated(); 
    // ... 
} 

参见:

+0

谢谢,但在我的情况是一个ManyToOne关系。我试着用Persistence.getPersistenceUtil()。IsLoaded()方法检查,但都没有工作。 –